/* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "client/mdns_utils.h" #include namespace mdns { // .. std::optional mdns_parse_instance_name(std::string_view name) { CHECK(!name.empty()); // Return the whole name if it doesn't fall under .. or // . bool has_local_suffix = false; // Strip the local suffix, if any { std::string local_suffix = ".local"; local_suffix += android::base::EndsWith(name, ".") ? "." : ""; if (android::base::ConsumeSuffix(&name, local_suffix)) { if (name.empty()) { return std::nullopt; } has_local_suffix = true; } } std::string transport; // Strip the transport suffix, if any { std::string add_dot = (!has_local_suffix && android::base::EndsWith(name, ".")) ? "." : ""; std::array transport_suffixes{"._tcp", "._udp"}; for (const auto& t : transport_suffixes) { if (android::base::ConsumeSuffix(&name, t + add_dot)) { if (name.empty()) { return std::nullopt; } transport = t.substr(1); break; } } if (has_local_suffix && transport.empty()) { return std::nullopt; } } if (!has_local_suffix && transport.empty()) { return std::make_optional(name, "", ""); } // Split the service name from the instance name auto pos = name.rfind("."); if (pos == 0 || pos == std::string::npos || pos == name.size() - 1) { return std::nullopt; } return std::make_optional(name.substr(0, pos), name.substr(pos + 1), transport); } } // namespace mdns