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