| // Copyright (C) 2019 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. |
| |
| #ifndef IORAP_SRC_DB_APP_COMPONENT_NAME_H_ |
| #define IORAP_SRC_DB_APP_COMPONENT_NAME_H_ |
| |
| namespace iorap::db { |
| |
| struct AppComponentName { |
| std::string package; |
| std::string activity_name; |
| |
| // Turns the activity name to the fully qualified name. |
| // For example, if the activity name is ".MainActivity" and the package is |
| // foo.bar. Then the fully qualified name is foo.bar.MainActivity. |
| AppComponentName Canonicalize() const { |
| if (!activity_name.empty() && activity_name[0] == '.') { |
| return {package, package + activity_name}; |
| } |
| return {package, activity_name}; |
| } |
| |
| static bool HasAppComponentName(const std::string& s) { |
| return s.find('/') != std::string::npos; |
| } |
| |
| // "com.foo.bar/.A" -> {"com.foo.bar", ".A"} |
| static AppComponentName FromString(const std::string& s) { |
| constexpr const char delimiter = '/'; |
| |
| if (!HasAppComponentName(s)) { |
| return {std::move(s), ""}; |
| } |
| |
| std::string package = s.substr(0, s.find(delimiter)); |
| |
| std::string activity_name = s; |
| activity_name.erase(0, s.find(delimiter) + sizeof(delimiter)); |
| |
| return {std::move(package), std::move(activity_name)}; |
| } |
| |
| // {"com.foo.bar", ".A"} -> "com.foo.bar/.A" |
| std::string ToString() const { |
| return package + "/" + activity_name; |
| } |
| |
| /* |
| * '/' is encoded into %2F |
| * '%' is encoded into %25 |
| * |
| * This allows the component name to be be used as a file name |
| * ('/' is illegal due to being a path separator) with minimal |
| * munging. |
| */ |
| |
| // "com.foo.bar%2F.A%25" -> {"com.foo.bar", ".A%"} |
| static AppComponentName FromUrlEncodedString(const std::string& s) { |
| std::string cpy = s; |
| Replace(cpy, "%2F", "/"); |
| Replace(cpy, "%25", "%"); |
| |
| return FromString(cpy); |
| } |
| |
| // {"com.foo.bar", ".A%"} -> "com.foo.bar%2F.A%25" |
| std::string ToUrlEncodedString() const { |
| std::string s = ToString(); |
| Replace(s, "%", "%25"); |
| Replace(s, "/", "%2F"); |
| return s; |
| } |
| |
| /* |
| * '/' is encoded into @@ |
| * '%' is encoded into ^^ |
| * |
| * Two purpose: |
| * 1. This allows the package name to be used as a file name |
| * ('/' is illegal due to being a path separator) with minimal |
| * munging. |
| * 2. This allows the package name to be used in .mk file because |
| * '%' is a special char and cannot be easily escaped in Makefile. |
| * |
| * This is a workround for test purpose. |
| * Only package name is used because activity name varies on |
| * different testing framework. |
| * Hopefully, the double "@@" and "^^" are not used in other cases. |
| */ |
| // {"com.foo.bar", ".A%"} -> "com.foo.bar" |
| std::string ToMakeFileSafeEncodedPkgString() const { |
| std::string s = package; |
| Replace(s, "/", "@@"); |
| Replace(s, "%", "^^"); |
| return s; |
| } |
| |
| private: |
| static bool Replace(std::string& str, const std::string& from, const std::string& to) { |
| // TODO: call in a loop to replace all occurrences, not just the first one. |
| const size_t start_pos = str.find(from); |
| if (start_pos == std::string::npos) { |
| return false; |
| } |
| |
| str.replace(start_pos, from.length(), to); |
| |
| return true; |
| } |
| }; |
| |
| inline std::ostream& operator<<(std::ostream& os, const AppComponentName& name) { |
| os << name.ToString(); |
| return os; |
| } |
| |
| } // namespace iorap::db |
| |
| #endif // IORAP_SRC_DB_APP_COMPONENT_NAME_H_ |