LMMS
Loading...
Searching...
No Matches
IoHelper.h
Go to the documentation of this file.
1/*
2 * IoHelper.h - helper functions for file I/O
3 *
4 * Copyright (c) 2018 Hyunjin Song <tteu.ingog/at/gmail.com>
5 *
6 * This file is part of LMMS - https://lmms.io
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program (see COPYING); if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301 USA.
22 *
23 */
24
25// NOTE: The LMMS/zynaddsubfx repo contains a copy of this header.
26// If you modify this file, consider modifying it there as well.
27
28#ifndef LMMS_IO_HELPER_H
29#define LMMS_IO_HELPER_H
30
31#include <cstdio>
32#include <limits>
33#include <memory>
34#include <stdexcept>
35#include <string>
36#include <string_view>
37
38#ifdef _WIN32
39# ifndef NOMINMAX
40# define NOMINMAX
41# endif
42# include <windows.h>
43#endif
44
45#if defined(_WIN32) && !defined(__WINE__)
46# include <io.h>
47#elif __has_include(<unistd.h>)
48# include <unistd.h>
49#endif
50
51namespace lmms
52{
53
54
55#ifdef _WIN32
56
61inline std::unique_ptr<wchar_t[]> toWString(std::string_view utf8)
62{
63 std::unique_ptr<wchar_t[]> ret;
64 if (utf8.empty())
65 {
66 ret = std::make_unique<wchar_t[]>(1);
67 return ret;
68 }
69
70 if (utf8.length() > static_cast<std::size_t>(std::numeric_limits<int>::max()))
71 {
72 throw std::overflow_error{"toWString: input string is too long"};
73 }
74 const auto utf8Len = static_cast<int>(utf8.length());
75
76 int result = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8.data(), utf8Len, nullptr, 0);
77 if (result <= 0)
78 {
79 const DWORD error = ::GetLastError();
80 throw std::invalid_argument{"toWString: failed to get size of result string. error code: " + std::to_string(error)};
81 }
82
83 ret = std::make_unique<wchar_t[]>(result + 1); // includes null terminator
84 result = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8.data(), utf8Len, ret.get(), result);
85 if (result <= 0)
86 {
87 const DWORD error = ::GetLastError();
88 throw std::invalid_argument{"toWString: failed to convert. error code: " + std::to_string(error)};
89 }
90
91 return ret;
92}
93
94#endif // _WIN32
95
97inline std::FILE* fopenUtf8(const std::string& filename, const char* mode)
98{
99#if defined(_WIN32) && !defined(__WINE__)
100 return _wfopen(toWString(filename).get(), toWString(mode).get());
101#else
102 return std::fopen(filename.c_str(), mode);
103#endif
104}
105
107inline int fileToDescriptor(std::FILE* file, bool closeFile = true)
108{
109 if (file == nullptr) { return -1; }
110
111#if defined(_WIN32) && !defined(__WINE__)
112 int fh = _dup(_fileno(file));
113#else
114 int fh = dup(fileno(file));
115#endif
116
117 if (closeFile) { std::fclose(file); }
118 return fh;
119}
120
121
122} // namespace lmms
123
124#endif // LMMS_IO_HELPER_H
Definition AudioAlsa.cpp:35
std::FILE * fopenUtf8(const std::string &filename, const char *mode)
std::fopen wrapper that expects UTF-8 encoded filename and mode
Definition IoHelper.h:97
int fileToDescriptor(std::FILE *file, bool closeFile=true)
Returns the POSIX file descriptor of the given FILE.
Definition IoHelper.h:107
QString filename
Definition HydrogenImport.cpp:42
png_structrp int mode
Definition png.h:1139
unsigned int DWORD
Definition swell-types.h:164
int error
Definition extract.c:1038
int result
Definition process.c:1455
struct zdirent * file
Definition win32.c:1500