comparison mupdf-source/source/fitz/time.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 // Copyright (C) 2004-2025 Artifex Software, Inc.
2 //
3 // This file is part of MuPDF.
4 //
5 // MuPDF is free software: you can redistribute it and/or modify it under the
6 // terms of the GNU Affero General Public License as published by the Free
7 // Software Foundation, either version 3 of the License, or (at your option)
8 // any later version.
9 //
10 // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU Affero General Public License
16 // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
17 //
18 // Alternative licensing terms are available from the licensor.
19 // For commercial licensing, see <https://www.artifex.com/> or contact
20 // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
21 // CA 94129, USA, for further information.
22
23 #include "mupdf/fitz.h"
24
25 #include <sys/stat.h>
26
27 #ifdef _WIN32
28
29 #include <stdio.h>
30 #include <errno.h>
31 #include <time.h>
32 #include <windows.h>
33 #include <direct.h> /* for mkdir */
34
35 #ifndef _WINRT
36
37 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
38
39 int gettimeofday(struct timeval *tv, struct timezone *tz)
40 {
41 FILETIME ft;
42 unsigned __int64 tmpres = 0;
43
44 if (tv)
45 {
46 GetSystemTimeAsFileTime(&ft);
47
48 tmpres |= ft.dwHighDateTime;
49 tmpres <<= 32;
50 tmpres |= ft.dwLowDateTime;
51
52 tmpres /= 10; /*convert into microseconds*/
53 /*converting file time to unix epoch*/
54 tmpres -= DELTA_EPOCH_IN_MICROSECS;
55 tv->tv_sec = (long)(tmpres / 1000000UL);
56 tv->tv_usec = (long)(tmpres % 1000000UL);
57 }
58
59 return 0;
60 }
61
62 #endif /* !_WINRT */
63
64 static char *
65 utf8_from_wchar(const wchar_t *s)
66 {
67 const wchar_t *src = s;
68 char *d;
69 char *dst;
70 int len = 1;
71
72 while (*src)
73 {
74 len += fz_runelen(*src++);
75 }
76
77 d = Memento_label(malloc(len), "utf8_from_wchar");
78 if (d != NULL)
79 {
80 dst = d;
81 src = s;
82 while (*src)
83 {
84 dst += fz_runetochar(dst, *src++);
85 }
86 *dst = 0;
87 }
88 return d;
89 }
90
91 static wchar_t *
92 wchar_from_utf8(const char *s)
93 {
94 wchar_t *d, *r;
95 int c;
96 /* This allocation is larger than we need, but it's guaranteed
97 * to be safe. */
98 r = d = malloc((strlen(s) + 1) * sizeof(wchar_t));
99 if (!r)
100 return NULL;
101 while (*s) {
102 s += fz_chartorune(&c, s);
103 /* Truncating c to a wchar_t can be problematic if c
104 * is 0x10000. */
105 if (c >= 0x10000)
106 {
107 c -= 0x10000;
108 *d++ = 0xd800 + (c>>10);
109 c = 0xdc00 + (c&1023);
110 }
111 *d++ = c;
112 }
113 *d = 0;
114 return r;
115 }
116
117 void *
118 fz_fopen_utf8(const char *name, const char *mode)
119 {
120 wchar_t *wname, *wmode;
121 FILE *file;
122
123 wname = wchar_from_utf8(name);
124 if (wname == NULL)
125 {
126 return NULL;
127 }
128
129 wmode = wchar_from_utf8(mode);
130 if (wmode == NULL)
131 {
132 free(wname);
133 return NULL;
134 }
135
136 file = _wfopen(wname, wmode);
137
138 free(wname);
139 free(wmode);
140 return file;
141 }
142
143 int
144 fz_remove_utf8(const char *name)
145 {
146 wchar_t *wname;
147 int n;
148
149 wname = wchar_from_utf8(name);
150 if (wname == NULL)
151 {
152 errno = ENOMEM;
153 return -1;
154 }
155
156 n = _wremove(wname);
157
158 free(wname);
159 return n;
160 }
161
162 char **
163 fz_argv_from_wargv(int argc, wchar_t **wargv)
164 {
165 char **argv;
166 int i;
167
168 argv = Memento_label(calloc(argc, sizeof(char *)), "fz_argv");
169 if (argv == NULL)
170 {
171 fprintf(stderr, "Out of memory while processing command line args!\n");
172 exit(1);
173 }
174
175 for (i = 0; i < argc; i++)
176 {
177 argv[i] = Memento_label(utf8_from_wchar(wargv[i]), "fz_arg");
178 if (argv[i] == NULL)
179 {
180 fprintf(stderr, "Out of memory while processing command line args!\n");
181 exit(1);
182 }
183 }
184
185 return argv;
186 }
187
188 void
189 fz_free_argv(int argc, char **argv)
190 {
191 int i;
192 for (i = 0; i < argc; i++)
193 free(argv[i]);
194 free(argv);
195 }
196
197 int64_t
198 fz_stat_ctime(const char *path)
199 {
200 struct _stat info;
201 wchar_t *wpath;
202
203 wpath = wchar_from_utf8(path);
204 if (wpath == NULL)
205 return 0;
206
207 if (_wstat(wpath, &info) < 0) {
208 free(wpath);
209 return 0;
210 }
211
212 free(wpath);
213 return info.st_ctime;
214 }
215
216 int64_t
217 fz_stat_mtime(const char *path)
218 {
219 struct _stat info;
220 wchar_t *wpath;
221
222 wpath = wchar_from_utf8(path);
223 if (wpath == NULL)
224 return 0;
225
226 if (_wstat(wpath, &info) < 0) {
227 free(wpath);
228 return 0;
229 }
230
231 free(wpath);
232 return info.st_mtime;
233 }
234
235 int
236 fz_mkdir(char *path)
237 {
238 int ret;
239 wchar_t *wpath = wchar_from_utf8(path);
240
241 if (wpath == NULL)
242 return -1;
243
244 ret = _wmkdir(wpath);
245
246 free(wpath);
247
248 return ret;
249 }
250
251 #else
252
253 int64_t
254 fz_stat_ctime(const char *path)
255 {
256 struct stat info;
257 if (stat(path, &info) < 0)
258 return 0;
259 return info.st_ctime;
260 }
261
262 int64_t
263 fz_stat_mtime(const char *path)
264 {
265 struct stat info;
266 if (stat(path, &info) < 0)
267 return 0;
268 return info.st_mtime;
269 }
270
271 int
272 fz_mkdir(char *path)
273 {
274 return mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO);
275 }
276
277 #endif /* _WIN32 */