static void LoadCustomStrings(const string& FileName, std::unordered_map<string, string>& Strings) { const os::fs::file CustomFile(FileName, FILE_READ_DATA, FILE_SHARE_READ, nullptr, OPEN_EXISTING); if (!CustomFile) return; const auto CustomFileCodepage = GetFileCodepage(CustomFile, encoding::codepage::oem(), nullptr, false); string SavedLabel; for (const auto& i : enum_file_lines(CustomFile, CustomFileCodepage)) { string_view Label, Text; switch (parse_lng_line(trim(i.Str), true, Label, Text)) { case lng_line_type::label: SavedLabel = Label; break; case lng_line_type::text: Strings.emplace(std::move(SavedLabel), ConvertString(Text)); SavedLabel.clear(); break; case lng_line_type::both: Strings.emplace(Label, ConvertString(Text)); break; default: break; } } }
void language::load(const string& Path, const string& Language, int CountNeed) { SCOPED_ACTION(GuardLastError); auto Data = m_Data->create(); const auto LangFileData = OpenLangFile(Path, LangFileMask, Language); const auto& LangFile = std::get<0>(LangFileData); const auto LangFileCodePage = std::get<2>(LangFileData); if (!LangFile) { throw MAKE_EXCEPTION(exception, L"Cannot find language data"sv); } Data->m_FileName = LangFile.GetName(); if (CountNeed != -1) { Data->reserve(CountNeed); } std::unordered_map<string, size_t> id_map; string label, text; for (const auto& i: enum_file_lines(LangFile, LangFileCodePage)) { bool have_text; parse_lng_line(trim(i.Str), label, text, have_text); if (have_text) { auto idx = Data->size(); Data->add(ConvertString(text)); if (!label.empty()) { id_map[label] = idx; label.clear(); } } } // Проведем проверку на количество строк в LNG-файлах if (CountNeed != -1 && CountNeed != static_cast<int>(Data->size())) { throw MAKE_EXCEPTION(exception, Data->m_FileName + L": language data is incorrect or damaged"sv); } // try to load Far<LNG>.lng.custom file(s) // if (!id_map.empty()) { const auto& LoadStrings = [&](const string& FileName) { const os::fs::file CustomFile(FileName, FILE_READ_DATA, FILE_SHARE_READ, nullptr, OPEN_EXISTING); if (!CustomFile) return; const auto CustomFileCodepage = GetFileCodepage(CustomFile, encoding::codepage::oem(), nullptr, false); label.clear(); for (const auto& i: enum_file_lines(CustomFile, CustomFileCodepage)) { bool have_text; parse_lng_line(trim(i.Str), label, text, have_text); if (have_text && !label.empty()) { const auto found = id_map.find(label); if (found != id_map.end()) { Data->set_at(found->second, ConvertString(text)); } label.clear(); } } }; const auto CustomLngInSameDir = Data->m_FileName + L".custom"sv; const auto CustomLngInProfileDir = concat(Global->Opt->ProfilePath, L'\\', ExtractFileName(CustomLngInSameDir)); LoadStrings(CustomLngInSameDir); LoadStrings(CustomLngInProfileDir); } m_Data = std::move(Data); }
void language::load(const string& Path, const string& Language, int CountNeed) { SCOPED_ACTION(GuardLastError); auto Data = m_Data->create(); const auto [LangFile, LangFileName, LangFileCodePage] = OpenLangFile(Path, LangFileMask, Language); if (!LangFile) { throw MAKE_FAR_KNOWN_EXCEPTION(L"Cannot find language data"sv); } Data->m_FileName = LangFile.GetName(); if (CountNeed != -1) { Data->reserve(CountNeed); } // try to load Far<LNG>.lng.custom file(s) std::unordered_map<string, string> CustomStrings; const auto CustomLngInSameDir = Data->m_FileName + L".custom"sv; const auto CustomLngInProfileDir = concat(Global->Opt->ProfilePath, L'\\', ExtractFileName(CustomLngInSameDir)); LoadCustomStrings(CustomLngInSameDir, CustomStrings); LoadCustomStrings(CustomLngInProfileDir, CustomStrings); const auto LoadLabels = !CustomStrings.empty(); string SavedLabel; for (const auto& i: enum_file_lines(LangFile, LangFileCodePage)) { string_view Label, Text; switch (parse_lng_line(trim(i.Str), LoadLabels, Label, Text)) { case lng_line_type::label: SavedLabel = Label; break; case lng_line_type::text: if (LoadLabels) { const auto Iterator = CustomStrings.find(SavedLabel); if (Iterator != CustomStrings.cend()) { Text = Iterator->second; } SavedLabel.clear(); } Data->add(ConvertString(Text)); break; default: break; } } // Проведем проверку на количество строк в LNG-файлах if (CountNeed != -1 && CountNeed != static_cast<int>(Data->size())) { throw MAKE_FAR_KNOWN_EXCEPTION(Data->m_FileName + L": language data is incorrect or damaged"sv); } m_Data = std::move(Data); }