From 4e1c76f34b910c6e9a832cbac2e2bcce8acc9f52 Mon Sep 17 00:00:00 2001 From: "estade@chromium.org" Date: Fri, 13 Nov 2009 01:36:50 +0000 Subject: Use renderer spellchecker for windows. BUG=25677 Review URL: http://codereview.chromium.org/372075 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31875 0039d316-1c4b-4281-b951-d872f2087c98 --- base/file_util.cc | 27 +++++++ base/file_util.h | 20 +++--- base/file_util_posix.cc | 42 +++-------- base/file_util_win.cc | 5 +- build/common.gypi | 10 +-- chrome/browser/profile.cc | 4 +- .../renderer_host/browser_render_process_host.cc | 16 ++++- chrome/browser/spellcheck_host.cc | 84 +++++++++++++++------- chrome/browser/spellcheck_host.h | 18 +++-- chrome/chrome.gyp | 23 +++--- chrome/common/notification_type.h | 2 - chrome/common/render_messages.h | 19 ++--- chrome/common/render_messages_internal.h | 3 +- chrome/renderer/render_thread.cc | 6 +- chrome/renderer/render_thread.h | 3 +- chrome/renderer/render_view.cc | 20 ++++-- chrome/renderer/spellchecker/spellcheck.cc | 14 ++-- chrome/renderer/spellchecker/spellcheck.h | 10 +-- ipc/ipc.gyp | 1 + ipc/ipc_platform_file.h | 35 +++++++++ 20 files changed, 229 insertions(+), 133 deletions(-) create mode 100644 ipc/ipc_platform_file.h diff --git a/base/file_util.cc b/base/file_util.cc index 4cde773..8d1b517 100644 --- a/base/file_util.cc +++ b/base/file_util.cc @@ -267,6 +267,20 @@ MemoryMappedFile::~MemoryMappedFile() { CloseHandles(); } +bool MemoryMappedFile::Initialize(base::PlatformFile file) { + if (IsValid()) + return false; + + file_ = file; + + if (!MapFileToMemoryInternal()) { + CloseHandles(); + return false; + } + + return true; +} + bool MemoryMappedFile::Initialize(const FilePath& file_name) { if (IsValid()) return false; @@ -279,6 +293,19 @@ bool MemoryMappedFile::Initialize(const FilePath& file_name) { return true; } +bool MemoryMappedFile::MapFileToMemory(const FilePath& file_name) { + file_ = base::CreatePlatformFile(file_name, + base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, + NULL); + + if (file_ == base::kInvalidPlatformFileValue) { + LOG(ERROR) << "Couldn't open " << file_name.value(); + return false; + } + + return MapFileToMemoryInternal(); +} + bool MemoryMappedFile::IsValid() { return data_ != NULL; } diff --git a/base/file_util.h b/base/file_util.h index 8654e62..782a6a2 100644 --- a/base/file_util.h +++ b/base/file_util.h @@ -24,6 +24,7 @@ #include "base/basictypes.h" #include "base/file_path.h" +#include "base/platform_file.h" #include "base/scoped_ptr.h" #include "base/string16.h" #include "base/time.h" @@ -490,10 +491,9 @@ class MemoryMappedFile { // the file does not exist, or the memory mapping fails, it will return false. // Later we may want to allow the user to specify access. bool Initialize(const FilePath& file_name); -#if defined(OS_POSIX) - // As above, but works with an alreay-opened file. - bool Initialize(const base::FileDescriptor& fd); -#endif + // As above, but works with an already-opened file. MemoryMappedFile will take + // ownership of |file| and close it when done. + bool Initialize(base::PlatformFile file); const uint8* data() const { return data_; } size_t length() const { return length_; } @@ -502,23 +502,19 @@ class MemoryMappedFile { bool IsValid(); private: - // Map the file to memory, set data_ to that memory address. Return true on - // success, false on any kind of failure. This is a helper for Initialize(). + // Open the given file and pass it to MapFileToMemoryInternal(). bool MapFileToMemory(const FilePath& file_name); -#if defined(OS_POSIX) + // Map the file to memory, set data_ to that memory address. Return true on + // success, false on any kind of failure. This is a helper for Initialize(). bool MapFileToMemoryInternal(); -#endif // Closes all open handles. Later we may want to make this public. void CloseHandles(); + base::PlatformFile file_; #if defined(OS_WIN) - HANDLE file_; HANDLE file_mapping_; -#elif defined(OS_POSIX) - // The file descriptor. - base::FileDescriptor file_; #endif uint8* data_; size_t length_; diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc index 1a05d79..a269d3f 100644 --- a/base/file_util_posix.cc +++ b/base/file_util_posix.cc @@ -667,47 +667,23 @@ bool FileEnumerator::ReadDirectory(std::vector* entries, // MemoryMappedFile MemoryMappedFile::MemoryMappedFile() - : data_(NULL), + : file_(base::kInvalidPlatformFileValue), + data_(NULL), length_(0) { } -bool MemoryMappedFile::Initialize(const base::FileDescriptor& fd) { - if (IsValid()) - return false; - - file_ = fd; - - if (!MapFileToMemoryInternal()) { - CloseHandles(); - return false; - } - - return true; -} - -bool MemoryMappedFile::MapFileToMemory(const FilePath& file_name) { - file_ = base::FileDescriptor(open(file_name.value().c_str(), O_RDONLY), true); - - if (file_.fd == -1) { - LOG(ERROR) << "Couldn't open " << file_name.value(); - return false; - } - - return MapFileToMemoryInternal(); -} - bool MemoryMappedFile::MapFileToMemoryInternal() { struct stat file_stat; - if (fstat(file_.fd, &file_stat) == -1) { - LOG(ERROR) << "Couldn't fstat " << file_.fd << ", errno " << errno; + if (fstat(file_, &file_stat) == base::kInvalidPlatformFileValue) { + LOG(ERROR) << "Couldn't fstat " << file_ << ", errno " << errno; return false; } length_ = file_stat.st_size; data_ = static_cast( - mmap(NULL, length_, PROT_READ, MAP_SHARED, file_.fd, 0)); + mmap(NULL, length_, PROT_READ, MAP_SHARED, file_, 0)); if (data_ == MAP_FAILED) - LOG(ERROR) << "Couldn't mmap " << file_.fd << ", errno " << errno; + LOG(ERROR) << "Couldn't mmap " << file_ << ", errno " << errno; return data_ != MAP_FAILED; } @@ -715,12 +691,12 @@ bool MemoryMappedFile::MapFileToMemoryInternal() { void MemoryMappedFile::CloseHandles() { if (data_ != NULL) munmap(data_, length_); - if (file_.auto_close && file_.fd != -1) - close(file_.fd); + if (file_ != base::kInvalidPlatformFileValue) + close(file_); data_ = NULL; length_ = 0; - file_ = base::FileDescriptor(); + file_ = base::kInvalidPlatformFileValue; } } // namespace file_util diff --git a/base/file_util_win.cc b/base/file_util_win.cc index d6edc6f..3105d37 100644 --- a/base/file_util_win.cc +++ b/base/file_util_win.cc @@ -773,10 +773,7 @@ MemoryMappedFile::MemoryMappedFile() length_(INVALID_FILE_SIZE) { } -bool MemoryMappedFile::MapFileToMemory(const FilePath& file_name) { - file_ = ::CreateFile(file_name.value().c_str(), GENERIC_READ, - FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); +bool MemoryMappedFile::MapFileToMemoryInternal() { if (file_ == INVALID_HANDLE_VALUE) return false; diff --git a/build/common.gypi b/build/common.gypi index 1cc8cca..36a218a 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -45,12 +45,14 @@ 'target_arch%': 'bdict_fd().fd != -1; + spellcheck_host_ready_ = spellcheck_host_ && + spellcheck_host_->bdict_file() != base::kInvalidPlatformFileValue; NotificationService::current()->Notify( NotificationType::SPELLCHECK_HOST_REINITIALIZED, Source(this), NotificationService::NoDetails()); diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index ca3b1f3..1a301ee 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -57,6 +57,7 @@ #include "grit/generated_resources.h" #include "ipc/ipc_logging.h" #include "ipc/ipc_message.h" +#include "ipc/ipc_platform_file.h" #include "ipc/ipc_switches.h" #if defined(OS_WIN) @@ -1125,13 +1126,24 @@ void BrowserRenderProcessHost::InitSpellChecker() { SpellCheckHost* spellcheck_host = profile()->GetSpellCheckHost(); if (spellcheck_host) { PrefService* prefs = profile()->GetPrefs(); + IPC::PlatformFileForTransit file; +#if defined(OS_POSIX) + file = base::FileDescriptor(spellcheck_host->bdict_file(), false); +#elif defined(OS_WIN) + ::DuplicateHandle(::GetCurrentProcess(), spellcheck_host->bdict_file(), + process().handle(), &file, + 0, false, DUPLICATE_SAME_ACCESS); +#endif Send(new ViewMsg_SpellChecker_Init( - spellcheck_host->bdict_fd(), spellcheck_host->custom_words(), + file, + spellcheck_host->custom_words(), spellcheck_host->language(), prefs->GetBoolean(prefs::kEnableAutoSpellCorrect))); } else { Send(new ViewMsg_SpellChecker_Init( - base::FileDescriptor(), std::vector(), std::string(), + IPC::PlatformFileForTransit(), + std::vector(), + std::string(), false)); } } diff --git a/chrome/browser/spellcheck_host.cc b/chrome/browser/spellcheck_host.cc index c9fea3ecf..05e328d 100644 --- a/chrome/browser/spellcheck_host.cc +++ b/chrome/browser/spellcheck_host.cc @@ -121,6 +121,18 @@ FilePath GetVersionedFileName(const std::string& input_language, return dict_dir.AppendASCII(versioned_bdict_file_name); } +FilePath GetFirstChoiceFilePath(const std::string& language) { + FilePath dict_dir; + PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir); + return GetVersionedFileName(language, dict_dir); +} + +FilePath GetFallbackFilePath(const FilePath& first_choice) { + FilePath dict_dir; + PathService::Get(chrome::DIR_USER_DATA, &dict_dir); + return dict_dir.Append(first_choice.BaseName()); +} + } // namespace // Constructed on UI thread. @@ -129,29 +141,26 @@ SpellCheckHost::SpellCheckHost(Observer* observer, URLRequestContextGetter* request_context_getter) : observer_(observer), language_(language), + file_(base::kInvalidPlatformFileValue), tried_to_download_(false), request_context_getter_(request_context_getter) { DCHECK(observer_); DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); - // TODO(estade): for Windows, we need to fall back to DIR_USER_DATA if - // DIR_APP_DICTIONARIES is not writeable. - FilePath dict_dir; - PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir); - bdict_file_ = GetVersionedFileName(language, dict_dir); - FilePath personal_file_directory; PathService::Get(chrome::DIR_USER_DATA, &personal_file_directory); custom_dictionary_file_ = personal_file_directory.Append(chrome::kCustomDictionaryFileName); + bdict_file_path_ = GetFirstChoiceFilePath(language); + ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, - NewRunnableMethod(this, &SpellCheckHost::Initialize)); + NewRunnableMethod(this, &SpellCheckHost::InitializeDictionaryLocation)); } SpellCheckHost::~SpellCheckHost() { - if (fd_.fd != -1) - close(fd_.fd); + if (file_ != base::kInvalidPlatformFileValue) + base::ClosePlatformFile(file_); } void SpellCheckHost::UnsetObserver() { @@ -172,24 +181,39 @@ void SpellCheckHost::AddWord(const std::string& word) { Source(this), NotificationService::NoDetails()); } +void SpellCheckHost::InitializeDictionaryLocation() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); + +#if defined(OS_WIN) + // Check if the dictionary exists in the fallback location. If so, use it + // rather than downloading anew. + FilePath fallback = GetFallbackFilePath(bdict_file_path_); + if (!file_util::PathExists(bdict_file_path_) && + file_util::PathExists(fallback)) { + bdict_file_path_ = fallback; + } +#endif + + Initialize(); +} + void SpellCheckHost::Initialize() { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); if (!observer_) return; - // We set |auto_close| to false because we don't want IPC to close the fd. - // We will close it manually in the destructor. - fd_ = base::FileDescriptor(open(bdict_file_.value().c_str(), O_RDONLY), - false); + file_ = base::CreatePlatformFile(bdict_file_path_, + base::PLATFORM_FILE_READ | base::PLATFORM_FILE_OPEN, + NULL); // File didn't exist. Download it. - if (fd_.fd == -1 && !tried_to_download_) { + if (file_ == base::kInvalidPlatformFileValue && !tried_to_download_) { DownloadDictionary(); return; } - if (fd_.fd != -1) { + if (file_ != base::kInvalidPlatformFileValue) { // Load custom dictionary. std::string contents; file_util::ReadFileToString(custom_dictionary_file_, &contents); @@ -218,7 +242,7 @@ void SpellCheckHost::DownloadDictionary() { static const char kDownloadServerUrl[] = "http://cache.pack.google.com/edgedl/chrome/dict/"; GURL url = GURL(std::string(kDownloadServerUrl) + WideToUTF8( - l10n_util::ToLower(bdict_file_.BaseName().ToWStringHack()))); + l10n_util::ToLower(bdict_file_path_.BaseName().ToWStringHack()))); fetcher_.reset(new URLFetcher(url, URLFetcher::GET, this)); fetcher_->set_request_context(request_context_getter_.get()); tried_to_download_ = true; @@ -263,15 +287,27 @@ void SpellCheckHost::OnURLFetchComplete(const URLFetcher* source, } size_t bytes_written = - file_util::WriteFile(bdict_file_, data.data(), data.length()); + file_util::WriteFile(bdict_file_path_, data.data(), data.length()); if (bytes_written != data.length()) { - LOG(ERROR) << "Failure to save dictionary."; - // To avoid trying to load a partially saved dictionary, shortcut the - // Initialize() call. - ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, - NewRunnableMethod(this, - &SpellCheckHost::InformObserverOfInitialization)); - return; + bool success = false; +#if defined(OS_WIN) + bdict_file_path_ = GetFallbackFilePath(bdict_file_path_); + bytes_written = + file_util::WriteFile(GetFallbackFilePath(bdict_file_path_), + data.data(), data.length()); + if (bytes_written == data.length()) + success = true; +#endif + + if (!success) { + LOG(ERROR) << "Failure to save dictionary."; + // To avoid trying to load a partially saved dictionary, shortcut the + // Initialize() call. + ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, + NewRunnableMethod(this, + &SpellCheckHost::InformObserverOfInitialization)); + return; + } } Initialize(); diff --git a/chrome/browser/spellcheck_host.h b/chrome/browser/spellcheck_host.h index 8c2ef55..437b982 100644 --- a/chrome/browser/spellcheck_host.h +++ b/chrome/browser/spellcheck_host.h @@ -8,8 +8,8 @@ #include #include -#include "base/file_descriptor_posix.h" #include "base/file_path.h" +#include "base/platform_file.h" #include "base/ref_counted.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/net/url_fetcher.h" @@ -35,7 +35,7 @@ class SpellCheckHost : public base::RefCountedThreadSafe& custom_words() const { return custom_words_; } @@ -50,6 +50,14 @@ class SpellCheckHost : public base::RefCountedThreadSafe custom_words_; diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index cc5c492..5a4b209 100755 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -2118,6 +2118,8 @@ 'browser/shell_integration_mac.mm', 'browser/shell_integration_linux.cc', 'browser/shell_integration_win.cc', + 'browser/spellcheck_host.cc', + 'browser/spellcheck_host.h', 'browser/spellcheck_worditerator.cc', 'browser/spellcheck_worditerator.h', 'browser/spellchecker.cc', @@ -2560,8 +2562,6 @@ 'sources': [ 'browser/crash_handler_host_linux.h', 'browser/net/ssl_config_service_manager_pref.cc', - 'browser/spellcheck_host.cc', - 'browser/spellcheck_host.h', ], 'sources/': [ # Exclude most of printing. @@ -3379,6 +3379,10 @@ 'renderer/renderer_web_database_observer.h', 'renderer/socket_stream_dispatcher.cc', 'renderer/socket_stream_dispatcher.h', + 'renderer/spellchecker/spellcheck.cc', + 'renderer/spellchecker/spellcheck.h', + 'renderer/spellchecker/spellcheck_worditerator.cc', + 'renderer/spellchecker/spellcheck_worditerator.h', 'renderer/user_script_idle_scheduler.cc', 'renderer/user_script_idle_scheduler.h', 'renderer/user_script_slave.cc', @@ -3415,12 +3419,6 @@ '../build/linux/system.gyp:gtk', '../sandbox/sandbox.gyp:sandbox', ], - 'sources': [ - 'renderer/spellchecker/spellcheck.cc', - 'renderer/spellchecker/spellcheck.h', - 'renderer/spellchecker/spellcheck_worditerator.cc', - 'renderer/spellchecker/spellcheck_worditerator.h', - ], }], # Windows-specific rules. ['OS=="win"', { @@ -3434,6 +3432,15 @@ '../third_party/tcmalloc/tcmalloc.gyp:tcmalloc', ], },], + # Mac-specific rules. + ['OS=="mac"', { + 'sources!': [ + 'renderer/spellchecker/spellcheck.cc', + 'renderer/spellchecker/spellcheck.h', + 'renderer/spellchecker/spellcheck_worditerator.cc', + 'renderer/spellchecker/spellcheck_worditerator.h', + ], + },], ], }, { diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h index f9597e3..3a98af6 100644 --- a/chrome/common/notification_type.h +++ b/chrome/common/notification_type.h @@ -551,7 +551,6 @@ class NotificationType { // profile. SPELLCHECKER_REINITIALIZED, -#if defined(SPELLCHECKER_IN_RENDERER) // Sent when SpellCheckHost has been reloaded. The source is the profile, // the details are NoDetails. SPELLCHECK_HOST_REINITIALIZED, @@ -559,7 +558,6 @@ class NotificationType { // Sent when a new word has been added to the custom dictionary. The source // is the SpellCheckHost, the details are NoDetails. SPELLCHECK_WORD_ADDED, -#endif // Sent when the bookmark bubble is shown for a particular URL. The source // is the profile, the details the URL. diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index c2410ce..3403448 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -12,6 +12,7 @@ #include "app/clipboard/clipboard.h" #include "app/gfx/native_widget_types.h" #include "base/basictypes.h" +#include "base/platform_file.h" #include "base/ref_counted.h" #include "base/shared_memory.h" #include "base/string16.h" @@ -31,6 +32,7 @@ #include "chrome/common/webkit_param_traits.h" #include "googleurl/src/gurl.h" #include "ipc/ipc_message_utils.h" +#include "ipc/ipc_platform_file.h" #include "media/audio/audio_output.h" #include "net/base/upload_data.h" #include "net/http/http_response_headers.h" @@ -50,12 +52,7 @@ #include "webkit/glue/webplugininfo.h" #include "webkit/glue/webpreferences.h" -#if defined(OS_WIN) -#include "base/platform_file.h" -#endif - #if defined(OS_POSIX) -#include "base/file_descriptor_posix.h" #endif namespace base { @@ -410,10 +407,8 @@ struct ViewMsg_PrintPages_Params { }; struct ViewMsg_DatabaseOpenFileResponse_Params { -#if defined(OS_WIN) - base::PlatformFile file_handle; // DB file handle -#elif defined(OS_POSIX) - base::FileDescriptor file_handle; // DB file handle + IPC::PlatformFileForTransit file_handle; // DB file handle +#if defined(OS_POSIX) base::FileDescriptor dir_handle; // DB directory handle #endif }; @@ -421,11 +416,7 @@ struct ViewMsg_DatabaseOpenFileResponse_Params { struct ViewMsg_OpenFileForPluginResponse_Params { // Note: if we end up having to add a directory handle, this should be // combined with the DatabaseOpenFileResponse_Params struct. -#if defined(OS_WIN) - base::PlatformFile file_handle; -#elif defined(OS_POSIX) - base::FileDescriptor file_handle; -#endif + IPC::PlatformFileForTransit file_handle; }; // Parameters to describe a rendered page. diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index a5c5f35..3d99dbe 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -29,6 +29,7 @@ #include "ipc/ipc_channel_handle.h" #include "ipc/ipc_message.h" #include "ipc/ipc_message_macros.h" +#include "ipc/ipc_platform_file.h" #include "third_party/skia/include/core/SkBitmap.h" #include "webkit/appcache/appcache_interfaces.h" #include "webkit/glue/dom_operations.h" @@ -839,7 +840,7 @@ IPC_BEGIN_MESSAGES(View) // be called directly after startup or in (async) response to a // RequestDictionary ViewHost message. IPC_MESSAGE_CONTROL4(ViewMsg_SpellChecker_Init, - base::FileDescriptor /* bdict_file */, + IPC::PlatformFileForTransit /* bdict_file */, std::vector /* custom_dict_words */, std::string /* language */, bool /* auto spell correct */) diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index a165b09..1222d67 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -58,6 +58,7 @@ #endif #include "chrome/renderer/user_script_slave.h" #include "ipc/ipc_message.h" +#include "ipc/ipc_platform_file.h" #include "third_party/tcmalloc/tcmalloc/src/google/malloc_extension.h" #include "third_party/WebKit/WebKit/chromium/public/WebCache.h" #include "third_party/WebKit/WebKit/chromium/public/WebColor.h" @@ -660,11 +661,12 @@ void RenderThread::OnPurgePluginListCache(bool reload_pages) { #if defined(SPELLCHECKER_IN_RENDERER) void RenderThread::OnInitSpellChecker( - const base::FileDescriptor& bdict_fd, + IPC::PlatformFileForTransit bdict_file, const std::vector& custom_words, const std::string& language, bool auto_spell_correct) { - spellchecker_->Init(bdict_fd, custom_words, language); + spellchecker_->Init(IPC::PlatformFileForTransitToPlatformFile(bdict_file), + custom_words, language); spellchecker_->EnableAutoSpellCorrect(auto_spell_correct); } diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h index d7f15a1..bca3ea6 100644 --- a/chrome/renderer/render_thread.h +++ b/chrome/renderer/render_thread.h @@ -18,6 +18,7 @@ #include "chrome/common/dom_storage_type.h" #include "chrome/renderer/renderer_histogram_snapshots.h" #include "chrome/renderer/visitedlink_slave.h" +#include "ipc/ipc_platform_file.h" class AppCacheDispatcher; class DBMessageFilter; @@ -200,7 +201,7 @@ class RenderThread : public RenderThreadBase, void OnPurgePluginListCache(bool reload_pages); #if defined(SPELLCHECKER_IN_RENDERER) - void OnInitSpellChecker(const base::FileDescriptor& bdict_fd, + void OnInitSpellChecker(IPC::PlatformFileForTransit bdict_file, const std::vector& custom_words, const std::string& language, bool auto_spell_correct); diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index aa8d86d..7541ceb 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -1505,9 +1505,13 @@ void RenderView::spellCheck(const WebString& text, #if defined(SPELLCHECKER_IN_RENDERER) string16 word(text); - RenderThread::current()->spellchecker()->SpellCheckWord( - word.c_str(), word.size(), document_tag_, - &misspelled_offset, &misspelled_length, NULL); + RenderThread* thread = RenderThread::current(); + // Will be NULL during unit tests. + if (thread) { + RenderThread::current()->spellchecker()->SpellCheckWord( + word.c_str(), word.size(), document_tag_, + &misspelled_offset, &misspelled_length, NULL); + } #else Send(new ViewHostMsg_SpellCheck(routing_id_, text, document_tag_, &misspelled_offset, &misspelled_length)); @@ -1520,9 +1524,13 @@ WebString RenderView::autoCorrectWord(const WebKit::WebString& word) { if (command_line.HasSwitch(switches::kExperimentalSpellcheckerFeatures)) { EnsureDocumentTag(); #if defined(SPELLCHECKER_IN_RENDERER) - autocorrect_word = - RenderThread::current()->spellchecker()->GetAutoCorrectionWord( - word, document_tag_); + RenderThread* thread = RenderThread::current(); + // Will be NULL during unit tests. + if (thread) { + autocorrect_word = + RenderThread::current()->spellchecker()->GetAutoCorrectionWord( + word, document_tag_); + } #else Send(new ViewHostMsg_GetAutoCorrectWord( routing_id_, word, document_tag_, &autocorrect_word)); diff --git a/chrome/renderer/spellchecker/spellcheck.cc b/chrome/renderer/spellchecker/spellcheck.cc index a565b08..3b02b54 100644 --- a/chrome/renderer/spellchecker/spellcheck.cc +++ b/chrome/renderer/spellchecker/spellcheck.cc @@ -16,7 +16,8 @@ static const int kMaxSuggestions = 5; using base::TimeTicks; SpellCheck::SpellCheck() - : auto_spell_correct_turned_on_(false), + : file_(base::kInvalidPlatformFileValue), + auto_spell_correct_turned_on_(false), // TODO(estade): initialize this properly. is_using_platform_spelling_engine_(false), initialized_(false) { @@ -26,13 +27,13 @@ SpellCheck::SpellCheck() SpellCheck::~SpellCheck() { } -void SpellCheck::Init(const base::FileDescriptor& fd, +void SpellCheck::Init(base::PlatformFile file, const std::vector& custom_words, const std::string language) { initialized_ = true; hunspell_.reset(); bdict_file_.reset(); - fd_ = fd; + file_ = file; character_attributes_.SetDefaultLanguage(language); custom_words_.insert(custom_words_.end(), @@ -57,7 +58,7 @@ bool SpellCheck::SpellCheckWord( return true; // Do nothing if spell checking is disabled. - if (initialized_ && fd_.fd == -1) + if (initialized_ && file_ == base::kInvalidPlatformFileValue) return true; *misspelling_start = 0; @@ -164,7 +165,7 @@ void SpellCheck::InitializeHunspell() { bdict_file_.reset(new file_util::MemoryMappedFile); - if (bdict_file_->Initialize(fd_)) { + if (bdict_file_->Initialize(file_)) { TimeTicks start_time = TimeTicks::Now(); hunspell_.reset( @@ -194,7 +195,8 @@ bool SpellCheck::InitializeIfNeeded() { } // Check if the platform spellchecker is being used. - if (!is_using_platform_spelling_engine_ && fd_.fd != -1) { + if (!is_using_platform_spelling_engine_ && + file_ != base::kInvalidPlatformFileValue) { // If it isn't, init hunspell. InitializeHunspell(); } diff --git a/chrome/renderer/spellchecker/spellcheck.h b/chrome/renderer/spellchecker/spellcheck.h index 3b2e19d..eb3ad82 100644 --- a/chrome/renderer/spellchecker/spellcheck.h +++ b/chrome/renderer/spellchecker/spellcheck.h @@ -10,7 +10,7 @@ #include #include "app/l10n_util.h" -#include "base/file_descriptor_posix.h" +#include "base/platform_file.h" #include "base/string16.h" #include "base/time.h" #include "chrome/renderer/spellchecker/spellcheck_worditerator.h" @@ -18,10 +18,6 @@ class Hunspell; -namespace base { -class FileDescriptor; -} - namespace file_util { class MemoryMappedFile; } @@ -32,7 +28,7 @@ class SpellCheck { ~SpellCheck(); - void Init(const base::FileDescriptor& bdict_fd, + void Init(base::PlatformFile file, const std::vector& custom_words, const std::string language); @@ -101,7 +97,7 @@ class SpellCheck { // The hunspell dictionary in use. scoped_ptr hunspell_; - base::FileDescriptor fd_; + base::PlatformFile file_; std::vector custom_words_; // Represents character attributes used for filtering out characters which diff --git a/ipc/ipc.gyp b/ipc/ipc.gyp index 8f2698c..8e393be 100644 --- a/ipc/ipc.gyp +++ b/ipc/ipc.gyp @@ -52,6 +52,7 @@ 'ipc_message_macros.h', 'ipc_message_utils.cc', 'ipc_message_utils.h', + 'ipc_platform_file.h', 'ipc_switches.cc', 'ipc_switches.h', 'ipc_sync_channel.cc', diff --git a/ipc/ipc_platform_file.h b/ipc/ipc_platform_file.h new file mode 100644 index 0000000..4307412 --- /dev/null +++ b/ipc/ipc_platform_file.h @@ -0,0 +1,35 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IPC_IPC_PLATFORM_FILE_H_ +#define IPC_IPC_PLATFORM_FILE_H_ + +#include "base/basictypes.h" + +#include "base/platform_file.h" + +#if defined(OS_POSIX) +#include "base/file_descriptor_posix.h" +#endif + +namespace IPC { + +#if defined(OS_WIN) +typedef base::PlatformFile PlatformFileForTransit; +#elif defined(OS_POSIX) +typedef base::FileDescriptor PlatformFileForTransit; +#endif + +inline base::PlatformFile PlatformFileForTransitToPlatformFile( + const PlatformFileForTransit& transit) { +#if defined(OS_WIN) + return transit; +#elif defined(OS_POSIX) + return transit.fd; +#endif +} + +} // namespace IPC + +#endif // IPC_IPC_PLATFORM_FILE_H_ -- cgit v1.1