Imported Upstream version 0.6.3
[fdkaac.git] / src / compat_win32.c
1 /*
2 * Copyright (C) 2013 nu774
3 * For conditions of distribution and use, see copyright notice in COPYING
4 */
5 #if HAVE_CONFIG_H
6 # include "config.h"
7 #endif
8 #if HAVE_STDINT_H
9 # include <stdint.h>
10 #endif
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <stdarg.h>
15 #include <assert.h>
16 #include <io.h>
17 #include <fcntl.h>
18 #include <share.h>
19 #include <sys/timeb.h>
20 #include "compat.h"
21 #define WIN32_LEAN_AND_MEAN
22 #include <windows.h>
23 #include <shellapi.h>
24
25 int64_t aacenc_timer(void)
26 {
27 #if HAVE_STRUCT___TIMEB64
28 struct __timeb64 tv;
29 _ftime64(&tv);
30 #else
31 struct timeb tv;
32 ftime(&tv);
33 #endif
34 return (int64_t)tv.time * 1000 + tv.millitm;
35 }
36
37 int aacenc_seekable(FILE *fp)
38 {
39 return GetFileType((HANDLE)_get_osfhandle(_fileno(fp))) == FILE_TYPE_DISK;
40 }
41
42 static
43 int codepage_decode_wchar(int codepage, const char *from, wchar_t **to)
44 {
45 int nc = MultiByteToWideChar(codepage, 0, from, -1, 0, 0);
46 if (nc == 0)
47 return -1;
48 *to = malloc(nc * sizeof(wchar_t));
49 MultiByteToWideChar(codepage, 0, from, -1, *to, nc);
50 return 0;
51 }
52
53 static
54 int codepage_encode_wchar(int codepage, const wchar_t *from, char **to)
55 {
56 int nc = WideCharToMultiByte(codepage, 0, from, -1, 0, 0, 0, 0);
57 if (nc == 0)
58 return -1;
59 *to = malloc(nc);
60 WideCharToMultiByte(codepage, 0, from, -1, *to, nc, 0, 0);
61 return 0;
62 }
63
64 FILE *aacenc_fopen(const char *name, const char *mode)
65 {
66 wchar_t *wname, *wmode;
67 FILE *fp;
68
69 if (strcmp(name, "-") == 0) {
70 fp = (mode[0] == 'r') ? stdin : stdout;
71 _setmode(_fileno(fp), _O_BINARY);
72 } else {
73 int share = _SH_DENYRW;
74 if (strchr(mode, 'r') && !strchr(mode, '+'))
75 share = _SH_DENYWR;
76 codepage_decode_wchar(CP_UTF8, name, &wname);
77 codepage_decode_wchar(CP_UTF8, mode, &wmode);
78 fp = _wfsopen(wname, wmode, share);
79 free(wname);
80 free(wmode);
81 }
82 return fp;
83 }
84
85 static char **__aacenc_argv__;
86
87 static
88 void aacenc_free_mainargs(void)
89 {
90 char **p = __aacenc_argv__;
91 for (; *p; ++p)
92 free(*p);
93 free(__aacenc_argv__);
94 }
95
96 void aacenc_getmainargs(int *argc, char ***argv)
97 {
98 int i;
99 wchar_t **wargv;
100
101 wargv = CommandLineToArgvW(GetCommandLineW(), argc);
102 *argv = malloc((*argc + 1) * sizeof(char*));
103 for (i = 0; i < *argc; ++i)
104 codepage_encode_wchar(CP_UTF8, wargv[i], &(*argv)[i]);
105 LocalFree(wargv);
106 (*argv)[*argc] = 0;
107 __aacenc_argv__ = *argv;
108 atexit(aacenc_free_mainargs);
109 }
110
111 char *aacenc_to_utf8(const char *s)
112 {
113 return _strdup(s);
114 }
115
116 #if defined(__MINGW32__) && !defined(HAVE__VSCPRINTF)
117 int _vscprintf(const char *fmt, va_list ap)
118 {
119 static int (*fp_vscprintf)(const char *, va_list) = 0;
120 if (!fp_vscprintf) {
121 HANDLE h = GetModuleHandleA("msvcrt.dll");
122 FARPROC fp = GetProcAddress(h, "_vscprintf");
123 InterlockedCompareExchangePointer(&fp_vscprintf, fp, 0);
124 }
125 assert(fp_vscprintf);
126 return fp_vscprintf(fmt, ap);
127 }
128 #endif
129
130 int aacenc_fprintf(FILE *fp, const char *fmt, ...)
131 {
132 va_list ap;
133 int cnt;
134 HANDLE fh = (HANDLE)_get_osfhandle(_fileno(fp));
135
136 if (GetFileType(fh) != FILE_TYPE_CHAR) {
137 va_start(ap, fmt);
138 cnt = vfprintf(fp, fmt, ap);
139 va_end(ap);
140 } else {
141 char *s;
142 wchar_t *ws;
143 DWORD nw;
144
145 va_start(ap, fmt);
146 cnt = _vscprintf(fmt, ap);
147 va_end(ap);
148
149 s = malloc(cnt + 1);
150
151 va_start(ap, fmt);
152 cnt = _vsnprintf(s, cnt + 1, fmt, ap);
153 va_end(ap);
154
155 codepage_decode_wchar(CP_UTF8, s, &ws);
156 free(s);
157 fflush(fp);
158 WriteConsoleW(fh, ws, wcslen(ws), &nw, 0);
159 free(ws);
160 }
161 return cnt;
162 }
163
164 const char *aacenc_basename(const char *path)
165 {
166 /*
167 * Since path is encoded with UTF-8, naive usage of strrchr() shoule be safe.
168 */
169 const char *p = strrchr(path, '/');
170 const char *q = strrchr(path, '\\');
171 const char *r = strrchr(path, ':');
172 if (q > p) p = q;
173 if (r > p) p = r;
174 return p ? p + 1 : path;
175 }
This page took 0.02448 seconds and 4 git commands to generate.