std::u32string StringToUTF32(const StringView str)
		{
			if (str.empty())
			{
				return std::u32string();
			}

			const wchar* begin = &str[0];
			const wchar* end = begin + str.length();

			if (const auto length = detail::CountCodePoints(begin, end))
			{
				std::u32string result(length.value(), L'\0');

				while (begin != end)
				{
					const auto ch = *begin++;

					if (!IsUTF16Surrogate(ch))
					{
						result.push_back(ch);
					}
					else
					{
						result.push_back(SurrogateToUTF32(ch, *begin++));
					}
				}

				return result;
			}
			else
			{
				return std::u32string();
			}
		}
Exemple #2
0
    void Write(StringView data)
    {
        NEPTOOLS_CHECK(SinkOverflow, offset+buf_put+data.length() <= size,
                       "Sink overflow during write");
        auto cp = std::min(data.length(), size_t(buf_size - buf_put));
        memcpy(buf+buf_put, data.data(), cp);
        data.remove_prefix(cp);
        buf_put += cp;

        if (!data.empty()) Write_(data);
    }
Exemple #3
0
void ExtractProtocol::execute(Pos data, size_t size, Pos & res_data, size_t & res_size)
{
	res_data = data;
	res_size = 0;

	StringView scheme = getURLScheme(StringView(data, size));
	Pos pos = data + scheme.size();

	if (scheme.empty() || (data + size) - pos < 4)
		return;

	if (pos[0] == ':')
		res_size = pos - data;
}
bool AbstractParser::evalSpecialCommandMap(StringView args)
{
    if (args.empty())
        return false;

    auto first = args.takeFirstWord();
    auto &map = m_specialCommandMap;

    const std::string key = first.toQString().toStdString();
    auto it = map.find(key);
    if (it == map.end())
        return false;

    // REVISIT: add # of calls to the record?
    ParserRecord &rec = it->second;
    const auto qs = QString::fromStdString(rec.fullCommand);
    const auto matched = std::vector<StringView>{StringView{qs}};
    return rec.callback(matched, args);
}
inline bool requiresNameAnnounced(const StringView &from_name,
                                  const StringView &from_ref,
                                  const StringView &from_pronunciation,
                                  const StringView &from_exits,
                                  const StringView &to_name,
                                  const StringView &to_ref,
                                  const StringView &to_pronunciation,
                                  const StringView &to_exits,
                                  const SuffixTable &suffix_table)
{
    // first is empty and the second is not
    if ((from_name.empty() && from_ref.empty()) && !(to_name.empty() && to_ref.empty()))
        return true;

    // FIXME, handle in profile to begin with?
    // Input for this function should be a struct separating streetname, suffix (e.g. road,
    // boulevard, North, West ...), and a list of references

    // check similarity of names
    const auto names_are_empty = from_name.empty() && to_name.empty();
    const auto name_is_contained =
        boost::starts_with(from_name, to_name) || boost::starts_with(to_name, from_name);

    const auto checkForPrefixOrSuffixChange =
        [](const StringView &first, const StringView &second, const SuffixTable &suffix_table) {
            std::string first_prefix, first_suffix, second_prefix, second_suffix;
            std::tie(first_prefix, first_suffix, second_prefix, second_suffix) =
                decompose(first, second);

            const auto checkTable = [&](const std::string &str) {
                return str.empty() || suffix_table.isSuffix(str);
            };

            return checkTable(first_prefix) && checkTable(first_suffix) &&
                   checkTable(second_prefix) && checkTable(second_suffix);
        };

    const auto is_suffix_change = checkForPrefixOrSuffixChange(from_name, to_name, suffix_table);
    const auto names_are_equal = from_name == to_name || name_is_contained || is_suffix_change;
    const auto name_is_removed = !from_name.empty() && to_name.empty();
    // references are contained in one another
    const auto refs_are_empty = from_ref.empty() && to_ref.empty();
    const auto ref_is_contained =
        from_ref.empty() || to_ref.empty() ||
        (from_ref.find(to_ref) != std::string::npos || to_ref.find(from_ref) != std::string::npos);
    const auto ref_is_removed = !from_ref.empty() && to_ref.empty();

    const auto obvious_change =
        (names_are_empty && refs_are_empty) || (names_are_equal && ref_is_contained) ||
        (names_are_equal && refs_are_empty) || (ref_is_contained && name_is_removed) ||
        (names_are_equal && ref_is_removed) || is_suffix_change;

    const auto needs_announce =
        // " (Ref)" -> "Name " and reverse
        (from_name.empty() && !from_ref.empty() && !to_name.empty() && to_ref.empty()) ||
        (!from_name.empty() && from_ref.empty() && to_name.empty() && !to_ref.empty());

    const auto pronunciation_changes = from_pronunciation != to_pronunciation;

    // when exiting onto ramps, we need to be careful about exit numbers. These can often be only
    // assigned to the first part of the ramp
    //
    //  a . . b . c . . d
    //         ` e . . f
    //
    // could assign the exit number to `be` when exiting `abcd` instead of the full ramp.
    //
    // Issuing a new-name instruction here would result in the turn assuming the short segment to be
    // irrelevant and remove the exit number in a collapse scenario. We don't want to issue any
    // instruction from be-ef, since we only loose the exit number. So we want to make sure that we
    // don't just loose an exit number, when exits change
    const auto exits_change = from_exits != to_exits;
    const auto looses_exit = (names_are_equal && !from_exits.empty() && to_exits.empty());

    return !obvious_change || needs_announce || pronunciation_changes ||
           (exits_change && !looses_exit);
}