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