Quellcode-Bibliothek mozPersonalDictionary.cpp
Sprache: C
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* 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/. */
/** * This is the most braindead implementation of a personal dictionary possible. * There is not much complexity needed, though. It could be made much faster, * and probably should, but I don't see much need for more in terms of * interface. * * Allowing personal words to be associated with only certain dictionaries * maybe. * * TODO: * Implement the suggestion record.
*/
class mozPersonalDictionaryLoader final : public mozilla::Runnable { public: explicit mozPersonalDictionaryLoader(mozPersonalDictionary* dict)
: mozilla::Runnable("mozPersonalDictionaryLoader"), mDict(dict) {}
NS_IMETHOD Run() override {
mDict->SyncLoad();
// Release the dictionary on the main thread
NS_ReleaseOnMainThread("mozPersonalDictionaryLoader::mDict",
mDict.forget().downcast<mozIPersonalDictionary>());
return NS_OK;
}
private:
RefPtr<mozPersonalDictionary> mDict;
};
class mozPersonalDictionarySave final : public mozilla::Runnable { public: explicit mozPersonalDictionarySave(mozPersonalDictionary* aDict,
nsCOMPtr<nsIFile> aFile,
nsTArray<nsString>&& aDictWords)
: mozilla::Runnable("mozPersonalDictionarySave"),
mDictWords(std::move(aDictWords)),
mFile(aFile),
mDict(aDict) {}
// Get a buffered output stream 4096 bytes big, to optimize writes.
nsCOMPtr<nsIOutputStream> bufferedOutputStream;
res = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream),
outStream.forget(), 4096); if (NS_FAILED(res)) { return res;
}
uint32_t bytesWritten;
nsAutoCString utf8Key; for (uint32_t i = 0; i < mDictWords.Length(); ++i) {
CopyUTF16toUTF8(mDictWords[i], utf8Key);
bufferedOutputStream->Write(utf8Key.get(), utf8Key.Length(),
&bytesWritten);
bufferedOutputStream->Write("\n", 1, &bytesWritten);
}
nsCOMPtr<nsISafeOutputStream> safeStream =
do_QueryInterface(bufferedOutputStream);
NS_ASSERTION(safeStream, "expected a safe output stream!"); if (safeStream) {
res = safeStream->Finish(); if (NS_FAILED(res)) {
NS_WARNING( "failed to save personal dictionary file! possible data loss");
}
}
// Save is done, reset the state variable and notify those who are // waiting.
mDict->mSavePending = false;
mon.Notify();
// Leaving the block where 'mon' was declared will call the destructor // and unlock.
}
// Release the dictionary on the main thread.
NS_ReleaseOnMainThread("mozPersonalDictionarySave::mDict",
mDict.forget().downcast<mozIPersonalDictionary>());
NS_ENSURE_STATE(svc); // we want to reload the dictionary if the profile switches
nsresult rv = svc->AddObserver(this, "profile-do-change", true); if (NS_WARN_IF(NS_FAILED(rv))) { return rv;
}
void mozPersonalDictionary::WaitForLoad() { // If the dictionary is already loaded, we return straight away. if (mIsLoaded) { return;
}
// If the dictionary hasn't been loaded, we try to lock the same monitor // that the thread uses that does the load. This way the main thread will // be suspended until the monitor becomes available.
mozilla::MonitorAutoLock mon(mMonitor);
// The monitor has become available. This can have two reasons: // 1: The thread that does the load has finished. // 2: The thread that does the load hasn't even started. // In this case we need to wait. if (!mIsLoaded) {
mon.Wait();
}
}
// we're rereading to get rid of the old data -- we shouldn't have any, // but...
mDictionaryTable.Clear();
char16_t c;
uint32_t nRead; bool done = false; do { // read each line of text into the string array. if ((NS_OK != convStream->Read(&c, 1, &nRead)) || (nRead != 1)) break; while (!done && ((c == '\n') || (c == '\r'))) { if ((NS_OK != convStream->Read(&c, 1, &nRead)) || (nRead != 1))
done = true;
} if (!done) {
nsAutoString word; while ((c != '\n') && (c != '\r') && !done) {
word.Append(c); if ((NS_OK != convStream->Read(&c, 1, &nRead)) || (nRead != 1))
done = true;
}
mDictionaryTable.Insert(word);
}
} while (!done);
}
void mozPersonalDictionary::WaitForSave() { // If no save is pending, we return straight away. if (!mSavePending) { return;
}
// If a save is pending, we try to lock the same monitor that the thread uses // that does the save. This way the main thread will be suspended until the // monitor becomes available.
mozilla::MonitorAutoLock mon(mMonitorSave);
// The monitor has become available. This can have two reasons: // 1: The thread that does the save has finished. // 2: The thread that does the save hasn't even started. // In this case we need to wait. if (mSavePending) {
mon.Wait();
}
}
// FIXME Deinst -- get dictionary name from prefs;
res = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(theFile)); if (NS_FAILED(res)) return res; if (!theFile) return NS_ERROR_FAILURE;
res = theFile->Append(nsLiteralString(MOZ_PERSONAL_DICT_NAME)); if (NS_FAILED(res)) return res;
mDictionaryTable.Remove(aWord);
res = Save(); return res;
}
NS_IMETHODIMP
mozPersonalDictionary::IgnoreWord(const nsAString& aWord) { // avoid adding duplicate words to the ignore list
mIgnoreTable.EnsureInserted(aWord); return NS_OK;
}
NS_IMETHODIMP mozPersonalDictionary::Observe(nsISupports* aSubject, constchar* aTopic, const char16_t* aData) { if (!nsCRT::strcmp(aTopic, "profile-do-change")) { // The observer is registered in Init() which calls Load and in turn // LoadInternal(); i.e. Observe() can't be called before Load().
WaitForLoad();
mIsLoaded = false;
Load(); // load automatically clears out the existing dictionary table
} elseif (!nsCRT::strcmp(aTopic, "profile-before-change")) {
WaitForSave();
}
return NS_OK;
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.8Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.