diff --git a/gui/pinyindictmanager/filelistmodel.cpp b/gui/pinyindictmanager/filelistmodel.cpp index 7c3d1906..d210fe44 100644 --- a/gui/pinyindictmanager/filelistmodel.cpp +++ b/gui/pinyindictmanager/filelistmodel.cpp @@ -76,15 +76,15 @@ Qt::ItemFlags FileListModel::flags(const QModelIndex &index) const { void FileListModel::loadFileList() { beginResetModel(); fileList_.clear(); - auto files = StandardPath::global().multiOpen( - StandardPath::Type::PkgData, "pinyin/dictionaries", O_RDONLY, - filter::Suffix(".dict")); + auto files = StandardPath::global().locate(StandardPath::Type::PkgData, + "pinyin/dictionaries", + filter::Suffix(".dict")); std::map enableMap; for (const auto &file : files) { enableMap[file.first] = true; } - auto disableFiles = StandardPath::global().multiOpen( - StandardPath::Type::PkgData, "pinyin/dictionaries", O_RDONLY, + auto disableFiles = StandardPath::global().locate( + StandardPath::Type::PkgData, "pinyin/dictionaries", filter::Suffix(".dict.disable")); for (const auto &file : disableFiles) { // Remove .disable suffix. diff --git a/im/pinyin/pinyin.cpp b/im/pinyin/pinyin.cpp index 6064703d..af40463d 100644 --- a/im/pinyin/pinyin.cpp +++ b/im/pinyin/pinyin.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -482,33 +483,35 @@ void PinyinEngine::updateUI(InputContext *inputContext) { /// }}} /// Create spell candidate {{{ - int engNess; auto [parsedPy, parsedPyCursor] = state->context_.preeditWithCursor( libime::PinyinPreeditMode::RawText); if (*config_.spellEnabled && spell() && parsedPyCursor >= selectedSentence.size() && - selectedLength <= context.cursor() && - (engNess = englishNess(parsedPy, context.useShuangpin()))) { - parsedPyCursor -= selectedSentence.length(); - parsedPy = - parsedPy.substr(selectedSentence.size(), - parsedPyCursor > selectedSentence.length() - ? parsedPyCursor - selectedSentence.length() - : std::string::npos); - auto results = spell()->call( - "en", SpellProvider::Custom, pyBeforeCursor, engNess); - std::string bestSentence; - if (!candidates.empty()) { - bestSentence = candidates[0].toString(); - } - int position = 1; - for (auto &result : results) { - if (customCandidateSet.count(result) || - context.candidatesToCursorSet().count(result)) { - continue; + selectedLength <= context.cursor()) { + int engNess = englishNess(parsedPy, context.useShuangpin()); + if (engNess) { + parsedPyCursor -= selectedSentence.length(); + parsedPy = parsedPy.substr( + selectedSentence.size(), + parsedPyCursor > selectedSentence.length() + ? parsedPyCursor - selectedSentence.length() + : std::string::npos); + auto results = spell()->call( + "en", SpellProvider::Custom, pyBeforeCursor, engNess); + std::string bestSentence; + if (!candidates.empty()) { + bestSentence = candidates[0].toString(); + } + int position = 1; + for (auto &result : results) { + if (customCandidateSet.count(result) || + context.candidatesToCursorSet().count(result)) { + continue; + } + extraCandidates.push_back( + std::make_unique( + this, result, pyBeforeCursor.size(), position++)); } - extraCandidates.push_back(std::make_unique( - this, result, pyBeforeCursor.size(), position++)); } } /// }}} @@ -818,35 +821,30 @@ void PinyinEngine::loadSymbols(const StandardPathFile &file) { } } -void PinyinEngine::loadDict(StandardPathFile file, +void PinyinEngine::loadDict(const std::string &fullPath, std::list> &taskTokens) { - if (file.fd() < 0) { + if (fullPath.empty()) { return; } ime_->dict()->addEmptyDict(); - PINYIN_DEBUG() << "Loading pinyin dict " << file.path(); - auto path = file.path(); - std::packaged_task task( - [file = std::move(file)]() { - boost::iostreams::stream_buffer< - boost::iostreams::file_descriptor_source> - buffer(file.fd(), boost::iostreams::file_descriptor_flags:: - never_close_handle); - std::istream in(&buffer); - auto trie = libime::PinyinDictionary::load( - in, libime::PinyinDictFormat::Binary); - return trie; - }); + PINYIN_DEBUG() << "Loading pinyin dict " << fullPath; + std::packaged_task task([fullPath]() { + std::ifstream in(fullPath, std::ios::in | std::ios::binary); + auto trie = libime::PinyinDictionary::load( + in, libime::PinyinDictFormat::Binary); + return trie; + }); taskTokens.push_back(worker_.addTask( std::move(task), - [this, index = ime_->dict()->dictSize() - 1, - path](std::shared_future &future) { + [this, index = ime_->dict()->dictSize() - 1, fullPath]( + std::shared_future &future) { try { - PINYIN_DEBUG() << "Load pinyin dict " << path << " finished."; + PINYIN_DEBUG() + << "Load pinyin dict " << fullPath << " finished."; ime_->dict()->setTrie(index, future.get()); } catch (const std::exception &e) { - PINYIN_ERROR() << "Failed to load pinyin dict " << path << ": " - << e.what(); + PINYIN_ERROR() << "Failed to load pinyin dict " << fullPath + << ": " << e.what(); } })); } @@ -859,20 +857,19 @@ void PinyinEngine::loadBuiltInDict() { loadSymbols(file); } { - auto file = standardPath.open(StandardPath::Type::PkgData, - "pinyin/chaizi.dict", O_RDONLY); - loadDict(std::move(file), persistentTask_); + auto file = standardPath.locate(StandardPath::Type::PkgData, + "pinyin/chaizi.dict"); + loadDict(file, persistentTask_); } { - auto file = standardPath.open(StandardPath::Type::Data, - "libime/extb.dict", O_RDONLY); + auto file = + standardPath.locate(StandardPath::Type::Data, "libime/extb.dict"); // Try again with absolute libime path. - if (!file.isValid()) { - file = standardPath.open(StandardPath::Type::Data, - LIBIME_INSTALL_PKGDATADIR "/extb.dict", - O_RDONLY); + if (file.empty()) { + file = standardPath.locate(StandardPath::Type::Data, + LIBIME_INSTALL_PKGDATADIR "/extb.dict"); } - loadDict(std::move(file), persistentTask_); + loadDict(file, persistentTask_); } if (ime_->dict()->dictSize() != libime::TrieDictionary::UserDict + 1 + NumBuiltInDict) { @@ -882,12 +879,12 @@ void PinyinEngine::loadBuiltInDict() { void PinyinEngine::loadExtraDict() { const auto &standardPath = StandardPath::global(); - auto files = standardPath.multiOpen(StandardPath::Type::PkgData, - "pinyin/dictionaries", O_RDONLY, - filter::Suffix(".dict")); - auto disableFiles = standardPath.multiOpen(StandardPath::Type::PkgData, - "pinyin/dictionaries", O_RDONLY, - filter::Suffix(".dict.disable")); + auto files = + standardPath.locate(StandardPath::Type::PkgData, "pinyin/dictionaries", + filter::Suffix(".dict")); + auto disableFiles = + standardPath.locate(StandardPath::Type::PkgData, "pinyin/dictionaries", + filter::Suffix(".dict.disable")); FCITX_ASSERT(ime_->dict()->dictSize() >= libime::TrieDictionary::UserDict + NumBuiltInDict + 1) << "Dict size: " << ime_->dict()->dictSize(); diff --git a/im/pinyin/pinyin.h b/im/pinyin/pinyin.h index 6f850f14..9884c8db 100644 --- a/im/pinyin/pinyin.h +++ b/im/pinyin/pinyin.h @@ -427,7 +427,7 @@ class PinyinEngine final : public InputMethodEngineV3, void loadExtraDict(); void loadCustomPhrase(); void loadSymbols(const StandardPathFile &file); - void loadDict(StandardPathFile file, + void loadDict(const std::string &fullPath, std::list> &taskTokens); void saveCustomPhrase(); diff --git a/im/table/ime.cpp b/im/table/ime.cpp index 7925ce6b..3060eae8 100644 --- a/im/table/ime.cpp +++ b/im/table/ime.cpp @@ -8,15 +8,31 @@ #include #include #include +#include +#include #include +#include +#include #include #include #include #include #include +#include +#include +#include +#include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include namespace fcitx { @@ -156,18 +172,13 @@ TableIME::requestDict(const std::string &name) { } dict->removeAllExtra(); - auto extraDicts = StandardPath::global().multiOpen( + auto extraDicts = StandardPath::global().locate( StandardPath::Type::PkgData, - stringutils::concat("table/", name, ".dict.d"), O_RDONLY, + stringutils::concat("table/", name, ".dict.d"), BinaryOrTextDict()); for (const auto &[name, file] : extraDicts) { try { - boost::iostreams::stream_buffer< - boost::iostreams::file_descriptor_source> - buffer(file.fd(), - boost::iostreams::file_descriptor_flags:: - never_close_handle); - std::istream in(&buffer); + std::ifstream in(file, std::ios::in | std::ios::binary); const auto fileFormat = stringutils::endsWith(name, ".txt") ? libime::TableFormat::Text : libime::TableFormat::Binary; diff --git a/modules/chttrans/chttrans.cpp b/modules/chttrans/chttrans.cpp index e806800e..8ea4d463 100644 --- a/modules/chttrans/chttrans.cpp +++ b/modules/chttrans/chttrans.cpp @@ -6,29 +6,46 @@ */ #include "chttrans.h" +#include "chttrans-native.h" #include "config.h" +#include +#include +#include #include #include +#include #include #include #include #include +#include #include +#include +#include #include +#include +#include +#include +#include #include +#include #include +#include +#include +#include +#include #include +#include +#include + #ifdef ENABLE_OPENCC #include "chttrans-opencc.h" -#include -#include #ifdef HAS_BOOST_JSON +#include #include +#include #endif #endif -#include "chttrans-native.h" -#include -#include using namespace fcitx; @@ -112,7 +129,7 @@ Chttrans::Chttrans(fcitx::Instance *instance) : instance_(instance) { outputFilterConn_ = instance_->connect( [this](InputContext *inputContext, Text &text) { // Short cut for empty string. - if (text.size() <= 0) { + if (text.empty()) { return; } if (!toggleAction_.isParent(&inputContext->statusArea())) { @@ -231,6 +248,7 @@ void Chttrans::populateConfig() { void Chttrans::syncToConfig() { std::vector values_; + values_.reserve(enabledIM_.size()); for (const auto &id : enabledIM_) { values_.push_back(id); } @@ -247,20 +265,15 @@ const Configuration *Chttrans::getConfig() const { std::vector> profiles{ {"default", _("Default")}}; constexpr std::string_view JsonSuffix = ".json"; - auto files = openCCStandardPath().multiOpen( - StandardPath::Type::PkgData, ".", O_RDONLY, - filter::Suffix(std::string(JsonSuffix))); + auto files = + openCCStandardPath().locate(StandardPath::Type::PkgData, ".", + filter::Suffix(std::string(JsonSuffix))); profiles.reserve(files.size() + 1); // files is std::map, so file name is already sorted. for (const auto &file : files) { #ifdef HAS_BOOST_JSON try { - boost::iostreams::stream_buffer< - boost::iostreams::file_descriptor_source> - buffer(file.second.fd(), - boost::iostreams::file_descriptor_flags:: - never_close_handle); - std::istream in(&buffer); + std::ifstream in(file.second, std::ios::in | std::ios::binary); std::string strBuf(std::istreambuf_iterator(in), {}); auto jv = boost::json::parse(strBuf); const auto &obj = jv.as_object(); diff --git a/modules/punctuation/punctuation.cpp b/modules/punctuation/punctuation.cpp index c7a0c4b0..44b8b84b 100644 --- a/modules/punctuation/punctuation.cpp +++ b/modules/punctuation/punctuation.cpp @@ -6,22 +6,43 @@ */ #include "punctuation.h" #include "notifications_public.h" +#include #include #include +#include +#include #include +#include +#include #include +#include +#include +#include +#include #include +#include +#include #include +#include #include +#include +#include #include #include #include #include +#include #include #include #include +#include +#include +#include +#include +#include #include -#include +#include +#include #include using namespace fcitx; @@ -70,7 +91,7 @@ void PunctuationProfile::addEntry(uint32_t key, const std::string &value, puncMap_[key].push_back(p); std::string punc = utf8::UCS4ToUTF8(key); - auto configValue = punctuationMapConfig_.entries.mutableValue(); + auto *configValue = punctuationMapConfig_.entries.mutableValue(); configValue->emplace_back(); PunctuationMapEntryConfig &entryConfig = configValue->back(); entryConfig.key.setValue(punc); @@ -80,18 +101,16 @@ void PunctuationProfile::addEntry(uint32_t key, const std::string &value, void PunctuationProfile::load(std::istream &in) { puncMap_.clear(); - auto configValue = punctuationMapConfig_.entries.mutableValue(); + auto *configValue = punctuationMapConfig_.entries.mutableValue(); configValue->clear(); std::string strBuf; while (std::getline(in, strBuf)) { - auto pair = stringutils::trimInplace(strBuf); - std::string::size_type start = pair.first, end = pair.second; - if (start == end) { + std::string_view trimmed = stringutils::trimView(strBuf); + if (trimmed.empty()) { continue; } - std::string text(strBuf.begin() + start, strBuf.begin() + end); - auto tokens = stringutils::split(strBuf, FCITX_WHITESPACE); + auto tokens = stringutils::split(trimmed, FCITX_WHITESPACE); if (tokens.size() != 2 && tokens.size() != 3) { continue; } @@ -115,12 +134,12 @@ void PunctuationProfile::set(const RawConfig &config) { newConfig.load(config); puncMap_.clear(); - auto configValue = punctuationMapConfig_.entries.mutableValue(); + auto *configValue = punctuationMapConfig_.entries.mutableValue(); configValue->clear(); const auto &entries = *newConfig.entries; // remove duplicate entry - for (auto &entry : entries) { + for (const auto &entry : entries) { if (entry.key->empty() || entry.mapResult1->empty()) { continue; } @@ -138,7 +157,7 @@ void PunctuationProfile::save(std::string_view name) const { StandardPath::Type::PkgData, stringutils::concat("punctuation/", profilePrefix, name), [this](int fd) { - for (auto &entry : *punctuationMapConfig_.entries) { + for (const auto &entry : *punctuationMapConfig_.entries) { fs::safeWrite(fd, entry.key->data(), entry.key->size()); fs::safeWrite(fd, " ", sizeof(char)); fs::safeWrite(fd, entry.mapResult1->data(), @@ -175,7 +194,7 @@ PunctuationProfile::getPunctuations(uint32_t unicode) const { return {iter->second[0].first}; } std::vector result; - for (auto &punc : iter->second) { + for (const auto &punc : iter->second) { result.push_back(punc.first); if (!punc.second.empty()) { result.push_back(punc.second); @@ -335,14 +354,9 @@ Punctuation::Punctuation(Instance *instance) // Scan through the surrounding text if (!state->lastPuncStackBackup_.empty() && state->lastPuncStack_.empty()) { - auto range = - utf8::MakeUTF8CharRange(MakeIterRange(text.begin(), end)); - for (auto iter = std::begin(range); iter != std::end(range); - iter++) { - auto charRange = iter.charRange(); - std::string_view chr( - &*charRange.first, - std::distance(charRange.first, charRange.second)); + auto range = utf8::MakeUTF8StringViewRange( + MakeIterRange(text.begin(), end)); + for (std::string_view chr : range) { auto puncIter = std::find_if( state->lastPuncStackBackup_.begin(), state->lastPuncStackBackup_.end(), @@ -364,12 +378,12 @@ void Punctuation::reloadConfig() { } void Punctuation::loadProfiles() { - auto systemFiles = StandardPath::global().multiOpen( - StandardPath::Type::PkgData, "punctuation", O_RDONLY, + auto systemFiles = StandardPath::global().locate( + StandardPath::Type::PkgData, "punctuation", filter::Prefix(std::string(PunctuationProfile::profilePrefix)), filter::Not(filter::User())); - auto allFiles = StandardPath::global().multiOpen( - StandardPath::Type::PkgData, "punctuation", O_RDONLY, + auto allFiles = StandardPath::global().locate( + StandardPath::Type::PkgData, "punctuation", filter::Prefix(std::string(PunctuationProfile::profilePrefix))); // Remove non-exist profiles. @@ -392,28 +406,18 @@ void Punctuation::loadProfiles() { auto iter = systemFiles.find(file.first); const bool hasSystemFile = iter != systemFiles.end(); bool hasUserFile = true; - if (hasSystemFile && iter->second.path() == file.second.path()) { + if (hasSystemFile && iter->second == file.second) { hasUserFile = false; } try { if (hasSystemFile) { - boost::iostreams::stream_buffer< - boost::iostreams::file_descriptor_source> - buffer(iter->second.fd(), - boost::iostreams::file_descriptor_flags:: - never_close_handle); - std::istream in(&buffer); + std::ifstream in(iter->second, std::ios::in | std::ios::binary); profiles_[lang].loadSystem(in); } else { profiles_[lang].resetDefaultValue(); } if (hasUserFile) { - boost::iostreams::stream_buffer< - boost::iostreams::file_descriptor_source> - buffer(file.second.fd(), - boost::iostreams::file_descriptor_flags:: - never_close_handle); - std::istream in(&buffer); + std::ifstream in(file.second, std::ios::in | std::ios::binary); profiles_[lang].load(in); } } catch (const std::exception &e) { diff --git a/modules/punctuation/punctuation.h b/modules/punctuation/punctuation.h index 12db57cc..240e8a92 100644 --- a/modules/punctuation/punctuation.h +++ b/modules/punctuation/punctuation.h @@ -8,11 +8,16 @@ #define _PUNCTUATION_PUNCTUATION_H_ #include "punctuation_public.h" +#include #include #include #include +#include #include +#include #include +#include +#include #include #include #include @@ -20,6 +25,13 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include FCITX_CONFIGURATION( PunctuationConfig, @@ -61,7 +73,7 @@ class PunctuationProfile { void loadSystem(std::istream &in); void load(std::istream &in); void set(const fcitx::RawConfig &config); - void save(std::string_view lang) const; + void save(std::string_view name) const; void resetDefaultValue(); const std::pair &