michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef fopen_hooks_h__ michael@0: #define fopen_hooks_h__ michael@0: michael@0: /** michael@0: * This file is force-included in hunspell code. Its purpose is to add michael@0: * readahead to fopen() calls in hunspell without modifying its code, in order michael@0: * to ease future upgrades. michael@0: * michael@0: * This file is force-included through mozilla-config.h which is generated michael@0: * during the configure step. michael@0: */ michael@0: michael@0: #include "mozilla/FileUtils.h" michael@0: #include michael@0: #include michael@0: michael@0: #if defined(XP_WIN) michael@0: #include "nsNativeCharsetUtils.h" michael@0: #include "nsString.h" michael@0: michael@0: #include michael@0: #include michael@0: // Hunspell defines a function named near. Windef.h #defines near. michael@0: #undef near michael@0: // mozHunspell defines a function named RemoveDirectory. michael@0: #undef RemoveDirectory michael@0: #endif /* defined(XP_WIN) */ michael@0: michael@0: inline FILE* michael@0: hunspell_fopen_readahead(const char* filename, const char* mode) michael@0: { michael@0: if (!filename || !mode) { michael@0: return nullptr; michael@0: } michael@0: // Fall back to libc's fopen for modes not supported by ReadAheadFile michael@0: if (!strchr(mode, 'r') || strchr(mode, '+')) { michael@0: return fopen(filename, mode); michael@0: } michael@0: int fd = -1; michael@0: #if defined(XP_WIN) michael@0: // filename is obtained via the nsIFile::nativePath attribute, so michael@0: // it is using the Windows ANSI code page, NOT UTF-8! michael@0: nsAutoString utf16Filename; michael@0: nsresult rv = NS_CopyNativeToUnicode(nsDependentCString(filename), michael@0: utf16Filename); michael@0: if (NS_FAILED(rv)) { michael@0: return nullptr; michael@0: } michael@0: HANDLE handle = INVALID_HANDLE_VALUE; michael@0: mozilla::ReadAheadFile(utf16Filename.get(), 0, SIZE_MAX, &handle); michael@0: if (handle == INVALID_HANDLE_VALUE) { michael@0: return nullptr; michael@0: } michael@0: int flags = _O_RDONLY; michael@0: // MSVC CRT's _open_osfhandle only supports adding _O_TEXT, not _O_BINARY michael@0: if (strchr(mode, 't')) { michael@0: // Force translated mode michael@0: flags |= _O_TEXT; michael@0: } michael@0: // Import the Win32 fd into the CRT michael@0: fd = _open_osfhandle((intptr_t)handle, flags); michael@0: if (fd < 0) { michael@0: CloseHandle(handle); michael@0: return nullptr; michael@0: } michael@0: #else michael@0: mozilla::ReadAheadFile(filename, 0, SIZE_MAX, &fd); michael@0: if (fd < 0) { michael@0: return nullptr; michael@0: } michael@0: #endif /* defined(XP_WIN) */ michael@0: michael@0: FILE* file = fdopen(fd, mode); michael@0: if (!file) { michael@0: close(fd); michael@0: } michael@0: return file; michael@0: } michael@0: michael@0: #define fopen(filename, mode) hunspell_fopen_readahead(filename, mode) michael@0: michael@0: #endif /* fopen_hooks_h__ */ michael@0: