| 236 | } |
| 237 | |
| 238 | int CheckedFile::open64( const ustring &fileName, int flags, int mode ) |
| 239 | { |
| 240 | #if defined( _MSC_VER ) |
| 241 | |
| 242 | // Handle UTF-8 file names - Windows requires conversion to UTF-16 |
| 243 | #if ( ( defined( _MSVC_LANG ) && _MSVC_LANG >= 201703L ) || __cplusplus >= 201703L ) |
| 244 | // Ref: |
| 245 | // https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar |
| 246 | std::wstring widePath; |
| 247 | int sizeUtf16 = ::MultiByteToWideChar( CP_UTF8, 0, fileName.c_str(), -1, NULL, 0 ); |
| 248 | if ( sizeUtf16 > 0 ) |
| 249 | { |
| 250 | widePath.resize( sizeUtf16 + 1 ); |
| 251 | sizeUtf16 = |
| 252 | ::MultiByteToWideChar( CP_UTF8, 0, fileName.c_str(), -1, &widePath[0], sizeUtf16 ); |
| 253 | } |
| 254 | if ( sizeUtf16 <= 0 ) |
| 255 | { |
| 256 | throw E57_EXCEPTION2( ErrorOpenFailed, |
| 257 | "Error in converting file name to UTF16. fileName=" + fileName ); |
| 258 | } |
| 259 | #else |
| 260 | // Until C++17 |
| 261 | std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; |
| 262 | std::wstring widePath = converter.from_bytes( fileName ); |
| 263 | #endif |
| 264 | |
| 265 | // Ref: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/sopen-s-wsopen-s |
| 266 | int handle; |
| 267 | errno_t err = _wsopen_s( &handle, widePath.c_str(), flags, _SH_DENYNO, mode ); |
| 268 | if ( err != 0 ) |
| 269 | { |
| 270 | // MSVC doesn't implement strerrorlen_s for some unknown reason, so just disable the warning |
| 271 | #pragma warning( push ) |
| 272 | #pragma warning( disable : 4996 ) |
| 273 | |
| 274 | throw E57_EXCEPTION2( ErrorOpenFailed, "errno=" + toString( errno ) + " error='" + |
| 275 | strerror( errno ) + "' fileName=" + fileName + |
| 276 | " flags=" + toString( flags ) + |
| 277 | " mode=" + toString( mode ) ); |
| 278 | |
| 279 | #pragma warning( pop ) |
| 280 | } |
| 281 | return handle; |
| 282 | #elif defined( __GNUC__ ) |
| 283 | int fd = ::open( fileName_.c_str(), flags, mode ); |
| 284 | if ( fd < 0 ) |
| 285 | { |
| 286 | throw E57_EXCEPTION2( ErrorOpenFailed, "errno=" + toString( errno ) + " error='" + |
| 287 | strerror( errno ) + "' fileName=" + fileName + |
| 288 | " flags=" + toString( flags ) + |
| 289 | " mode=" + toString( mode ) ); |
| 290 | } |
| 291 | return fd; |
| 292 | #else |
| 293 | #error "no supported compiler defined" |
| 294 | #endif |
| 295 | } |