| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h" | 5 #include "chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h" |
| 6 | 6 |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 if (descriptor != base::kInvalidPlatformFileValue) { | 42 if (descriptor != base::kInvalidPlatformFileValue) { |
| 43 BrowserThread::PostTask( | 43 BrowserThread::PostTask( |
| 44 BrowserThread::FILE, | 44 BrowserThread::FILE, |
| 45 FROM_HERE, | 45 FROM_HERE, |
| 46 base::Bind(&CloseDictionary, descriptor)); | 46 base::Bind(&CloseDictionary, descriptor)); |
| 47 descriptor = base::kInvalidPlatformFileValue; | 47 descriptor = base::kInvalidPlatformFileValue; |
| 48 } | 48 } |
| 49 } | 49 } |
| 50 | 50 |
| 51 // The desired location of the dictionary file, whether or not it exists. | 51 // The desired location of the dictionary file, whether or not it exists. |
| 52 FilePath path; | 52 base::FilePath path; |
| 53 | 53 |
| 54 // The file descriptor/handle for the dictionary file. | 54 // The file descriptor/handle for the dictionary file. |
| 55 base::PlatformFile descriptor; | 55 base::PlatformFile descriptor; |
| 56 | 56 |
| 57 DISALLOW_COPY_AND_ASSIGN(DictionaryFile); | 57 DISALLOW_COPY_AND_ASSIGN(DictionaryFile); |
| 58 }; | 58 }; |
| 59 | 59 |
| 60 namespace { | 60 namespace { |
| 61 | 61 |
| 62 // Figures out the location for the dictionary, verifies its contents, and opens | 62 // Figures out the location for the dictionary, verifies its contents, and opens |
| 63 // it. The default place where the spellcheck dictionary resides is | 63 // it. The default place where the spellcheck dictionary resides is |
| 64 // chrome::DIR_APP_DICTIONARIES. For systemwide installations on Windows. | 64 // chrome::DIR_APP_DICTIONARIES. For systemwide installations on Windows. |
| 65 // however, this directory may not have permissions for download. In that case, | 65 // however, this directory may not have permissions for download. In that case, |
| 66 // the alternate directory for download is chrome::DIR_USER_DATA. Returns a | 66 // the alternate directory for download is chrome::DIR_USER_DATA. Returns a |
| 67 // scoped pointer to avoid leaking the file descriptor if the caller has been | 67 // scoped pointer to avoid leaking the file descriptor if the caller has been |
| 68 // destroyed. | 68 // destroyed. |
| 69 scoped_ptr<DictionaryFile> InitializeDictionaryLocation( | 69 scoped_ptr<DictionaryFile> InitializeDictionaryLocation( |
| 70 const std::string& language) { | 70 const std::string& language) { |
| 71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 72 scoped_ptr<DictionaryFile> file(new DictionaryFile); | 72 scoped_ptr<DictionaryFile> file(new DictionaryFile); |
| 73 | 73 |
| 74 // Initialize the BDICT path. Initialization should be in the FILE thread | 74 // Initialize the BDICT path. Initialization should be in the FILE thread |
| 75 // because it checks if there is a "Dictionaries" directory and create it. | 75 // because it checks if there is a "Dictionaries" directory and create it. |
| 76 FilePath dict_dir; | 76 base::FilePath dict_dir; |
| 77 PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir); | 77 PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir); |
| 78 file->path = chrome::spellcheck_common::GetVersionedFileName( | 78 file->path = chrome::spellcheck_common::GetVersionedFileName( |
| 79 language, dict_dir); | 79 language, dict_dir); |
| 80 | 80 |
| 81 #if defined(OS_WIN) | 81 #if defined(OS_WIN) |
| 82 // Check if the dictionary exists in the fallback location. If so, use it | 82 // Check if the dictionary exists in the fallback location. If so, use it |
| 83 // rather than downloading anew. | 83 // rather than downloading anew. |
| 84 base::FilePath user_dir; | 84 base::FilePath user_dir; |
| 85 PathService::Get(chrome::DIR_USER_DATA, &user_dir); | 85 PathService::Get(chrome::DIR_USER_DATA, &user_dir); |
| 86 FilePath fallback = user_dir.Append(file->path.BaseName()); | 86 base::FilePath fallback = user_dir.Append(file->path.BaseName()); |
| 87 if (!file_util::PathExists(file->path) && file_util::PathExists(fallback)) | 87 if (!file_util::PathExists(file->path) && file_util::PathExists(fallback)) |
| 88 file->path = fallback; | 88 file->path = fallback; |
| 89 #endif | 89 #endif |
| 90 | 90 |
| 91 // Read the dictionary file and scan its data to check for corruption. The | 91 // Read the dictionary file and scan its data to check for corruption. The |
| 92 // scoping closes the memory-mapped file before it is opened or deleted. | 92 // scoping closes the memory-mapped file before it is opened or deleted. |
| 93 bool bdict_is_valid; | 93 bool bdict_is_valid; |
| 94 { | 94 { |
| 95 file_util::MemoryMappedFile map; | 95 file_util::MemoryMappedFile map; |
| 96 bdict_is_valid = file_util::PathExists(file->path) && | 96 bdict_is_valid = file_util::PathExists(file->path) && |
| 97 map.Initialize(file->path) && | 97 map.Initialize(file->path) && |
| 98 hunspell::BDict::Verify(reinterpret_cast<const char*>(map.data()), | 98 hunspell::BDict::Verify(reinterpret_cast<const char*>(map.data()), |
| 99 map.length()); | 99 map.length()); |
| 100 } | 100 } |
| 101 if (bdict_is_valid) { | 101 if (bdict_is_valid) { |
| 102 file->descriptor = base::CreatePlatformFile( | 102 file->descriptor = base::CreatePlatformFile( |
| 103 file->path, | 103 file->path, |
| 104 base::PLATFORM_FILE_READ | base::PLATFORM_FILE_OPEN, | 104 base::PLATFORM_FILE_READ | base::PLATFORM_FILE_OPEN, |
| 105 NULL, | 105 NULL, |
| 106 NULL); | 106 NULL); |
| 107 } else { | 107 } else { |
| 108 file_util::Delete(file->path, false); | 108 file_util::Delete(file->path, false); |
| 109 } | 109 } |
| 110 | 110 |
| 111 return file.Pass(); | 111 return file.Pass(); |
| 112 } | 112 } |
| 113 | 113 |
| 114 // Saves |data| to file at |path|. Returns true on successful save, otherwise | 114 // Saves |data| to file at |path|. Returns true on successful save, otherwise |
| 115 // returns false. | 115 // returns false. |
| 116 bool SaveDictionaryData(scoped_ptr<std::string> data, const FilePath& path) { | 116 bool SaveDictionaryData(scoped_ptr<std::string> data, |
| 117 const base::FilePath& path) { |
| 117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 118 | 119 |
| 119 size_t bytes_written = | 120 size_t bytes_written = |
| 120 file_util::WriteFile(path, data->data(), data->length()); | 121 file_util::WriteFile(path, data->data(), data->length()); |
| 121 if (bytes_written != data->length()) { | 122 if (bytes_written != data->length()) { |
| 122 bool success = false; | 123 bool success = false; |
| 123 #if defined(OS_WIN) | 124 #if defined(OS_WIN) |
| 124 base::FilePath dict_dir; | 125 base::FilePath dict_dir; |
| 125 PathService::Get(chrome::DIR_USER_DATA, &dict_dir); | 126 PathService::Get(chrome::DIR_USER_DATA, &dict_dir); |
| 126 base::FilePath fallback_file_path = | 127 base::FilePath fallback_file_path = |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 void SpellcheckHunspellDictionary::InformListenersOfInitialization() { | 341 void SpellcheckHunspellDictionary::InformListenersOfInitialization() { |
| 341 FOR_EACH_OBSERVER(Observer, observers_, OnHunspellDictionaryInitialized()); | 342 FOR_EACH_OBSERVER(Observer, observers_, OnHunspellDictionaryInitialized()); |
| 342 } | 343 } |
| 343 | 344 |
| 344 void SpellcheckHunspellDictionary::InformListenersOfDownloadFailure() { | 345 void SpellcheckHunspellDictionary::InformListenersOfDownloadFailure() { |
| 345 download_status_ = DOWNLOAD_FAILED; | 346 download_status_ = DOWNLOAD_FAILED; |
| 346 FOR_EACH_OBSERVER(Observer, | 347 FOR_EACH_OBSERVER(Observer, |
| 347 observers_, | 348 observers_, |
| 348 OnHunspellDictionaryDownloadFailure()); | 349 OnHunspellDictionaryDownloadFailure()); |
| 349 } | 350 } |
| OLD | NEW |