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 |