1769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski/* 2769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * Copyright (C) 2015 The Android Open Source Project 3769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * 4769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * you may not use this file except in compliance with the License. 6769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * You may obtain a copy of the License at 7769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * 8769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * 10769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * Unless required by applicable law or agreed to in writing, software 11769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * See the License for the specific language governing permissions and 14769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * limitations under the License. 15769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski */ 16769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski 17769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski#ifndef AAPT_NAME_MANGLER_H 18769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski#define AAPT_NAME_MANGLER_H 19769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski 201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "Resource.h" 211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 221ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Maybe.h" 231ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 241ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include <set> 25769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski#include <string> 26769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski 27769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinskinamespace aapt { 28769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski 291ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct NameManglerPolicy { 301ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski /** 311ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Represents the package we are trying to build. References pointing 321ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * to this package are not mangled, and mangled references inherit this package name. 331ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 341ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski std::u16string targetPackageName; 351ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 361ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski /** 371ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * We must know which references to mangle, and which to keep (android vs. com.android.support). 381ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 391ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski std::set<std::u16string> packagesToMangle; 401ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 411ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 421ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiclass NameMangler { 431ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiprivate: 441ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski NameManglerPolicy mPolicy; 451ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 461ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskipublic: 471ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski NameMangler(NameManglerPolicy policy) : mPolicy(policy) { 481ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 491ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 501ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski Maybe<ResourceName> mangleName(const ResourceName& name) { 511ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski if (mPolicy.targetPackageName == name.package || 521ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski mPolicy.packagesToMangle.count(name.package) == 0) { 531ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski return {}; 541ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 551ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 561ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski return ResourceName{ 571ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski mPolicy.targetPackageName, 581ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski name.type, 591ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski mangleEntry(name.package, name.entry) 601ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski }; 611ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 621ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 63a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski bool shouldMangle(const std::u16string& package) const { 641ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski if (package.empty() || mPolicy.targetPackageName == package) { 651ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski return false; 661ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 671ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski return mPolicy.packagesToMangle.count(package) != 0; 681ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 691ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 70769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski /** 711ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Returns a mangled name that is a combination of `name` and `package`. 721ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * The mangled name should contain symbols that are illegal to define in XML, 731ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * so that there will never be name mangling collisions. 74769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski */ 751ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski static std::u16string mangleEntry(const std::u16string& package, const std::u16string& name) { 761ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski return package + u"$" + name; 77769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski } 78769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski 79769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski /** 80769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * Unmangles the name in `outName`, storing the correct name back in `outName` 81769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * and the package in `outPackage`. Returns true if the name was unmangled or 82769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski * false if the name was never mangled to begin with. 83769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski */ 84769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski static bool unmangle(std::u16string* outName, std::u16string* outPackage) { 85769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski size_t pivot = outName->find(u'$'); 86769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski if (pivot == std::string::npos) { 87769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski return false; 88769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski } 89769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski 90769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski outPackage->assign(outName->data(), pivot); 91769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski outName->assign(outName->data() + pivot + 1, outName->size() - (pivot + 1)); 92769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski return true; 93769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski } 94769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski}; 95769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski 96769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski} // namespace aapt 97769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski 98769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski#endif // AAPT_NAME_MANGLER_H 99