Exemplo n.º 1
0
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;
		}
	}
}
Exemplo n.º 2
0
bool GetLangParam(const os::fs::file& LangFile, string_view const ParamName, string& strParam1, string* strParam2, uintptr_t CodePage)
{
	const auto strFullParamName = concat(L'.', ParamName);
	const auto CurFilePos = LangFile.GetPointer();
	SCOPE_EXIT{ LangFile.SetPointer(CurFilePos, nullptr, FILE_BEGIN); };

	for (const auto& i: enum_file_lines(LangFile, CodePage))
	{
		if (starts_with_icase(i.Str, strFullParamName))
		{
			const auto EqPos = i.Str.find(L'=');

			if (EqPos != string::npos)
			{
				assign(strParam1, i.Str.substr(EqPos + 1));

				if (strParam2)
					strParam2->clear();

				const auto pos = strParam1.find(L',');

				if (pos != string::npos)
				{
					if (strParam2)
					{
						*strParam2 = trim_right(strParam1.substr(pos + 1));
					}

					strParam1.resize(pos);
				}

				inplace::trim_right(strParam1);
				return true;
			}
		}
		else if (starts_with(i.Str, L'"'))
		{
			// '"' indicates some meaningful string.
			// Parameters can be only in the header, no point to go deeper
			return false;
		}
	}

	return false;
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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);
}