|
22 | 22 | #ifndef PORTABLE_FMEMOPEN_H |
23 | 23 | #define PORTABLE_FMEMOPEN_H |
24 | 24 |
|
25 | | -#if defined(__APPLE__) || defined(__MACH__) |
| 25 | +#if defined(_WIN32) |
26 | 26 |
|
27 | | -// macOS does not have fmemopen, but has funopen |
| 27 | +// Windows has no fmemopen |
28 | 28 | static inline FILE* portable_fmemopen(void* buf, size_t size, const char* mode) |
29 | 29 | { |
30 | | - (void)mode; // Only "wb" or "rb" used in tests |
31 | | - |
32 | | - // Simple implementation: use a temporary file and preload the buffer |
33 | 30 | FILE* f = tmpfile(); |
| 31 | + |
34 | 32 | if (!f) |
35 | 33 | return NULL; |
36 | 34 |
|
37 | 35 | if (buf && size > 0 && strchr(mode, 'w') == NULL) { |
38 | | - // reading: preload buffer |
39 | 36 | fwrite(buf, 1, size, f); |
40 | 37 | rewind(f); |
41 | 38 | } |
42 | 39 |
|
43 | 40 | return f; |
44 | 41 | } |
45 | 42 |
|
46 | | -#elif defined(_WIN32) |
| 43 | +#else |
47 | 44 |
|
48 | | -// Windows also has no fmemopen |
| 45 | +// macOS does not have fmemopen, but has funopen |
| 46 | +// BSD may not have fmemopen |
| 47 | +// Most Linux distros do have fmemopen |
49 | 48 | static inline FILE* portable_fmemopen(void* buf, size_t size, const char* mode) |
50 | 49 | { |
| 50 | + (void)mode; // Only "wb" or "rb" used in tests |
| 51 | + |
| 52 | + // Simple implementation: use a temporary file and preload the buffer |
51 | 53 | FILE* f = tmpfile(); |
| 54 | + |
52 | 55 | if (!f) |
53 | 56 | return NULL; |
54 | 57 |
|
55 | 58 | if (buf && size > 0 && strchr(mode, 'w') == NULL) { |
| 59 | + // reading: preload buffer |
56 | 60 | fwrite(buf, 1, size, f); |
57 | 61 | rewind(f); |
58 | 62 | } |
59 | 63 |
|
60 | 64 | return f; |
61 | 65 | } |
62 | 66 |
|
63 | | -#else |
64 | | - |
65 | | -// Linux/glibc supports real fmemopen |
66 | | -static inline FILE* portable_fmemopen(void* buf, size_t size, const char* mode) |
67 | | -{ |
68 | | - return fmemopen(buf, size, mode); |
69 | | -} |
70 | | - |
71 | 67 | #endif |
72 | 68 |
|
73 | 69 | #endif |
|
0 commit comments