11ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/*
21ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Copyright (C) 2015 The Android Open Source Project
31ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
41ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
51ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * you may not use this file except in compliance with the License.
61ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * You may obtain a copy of the License at
71ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
81ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
91ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Unless required by applicable law or agreed to in writing, software
111ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * See the License for the specific language governing permissions and
141ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * limitations under the License.
151ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */
161ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
171ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "link/Linkers.h"
181ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
191ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include <algorithm>
201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include <iterator>
211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
22ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "android-base/logging.h"
23ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
24ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "ResourceTable.h"
25ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
261ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskinamespace aapt {
271ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
281ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename InputContainer, typename OutputIterator, typename Predicate>
29ceb9b2f80f853059233cdd29057f39a5960a74aeAdam LesinskiOutputIterator move_if(InputContainer& input_container, OutputIterator result, Predicate pred) {
30ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const auto last = input_container.end();
31ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski  auto new_end = std::find_if(input_container.begin(), input_container.end(), pred);
32ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (new_end == last) {
33cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return result;
34cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
351ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
36ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  *result = std::move(*new_end);
371ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
38ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  auto first = new_end;
39cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ++first;
401ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
41cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  for (; first != last; ++first) {
42cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (bool(pred(*first))) {
43cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      // We want to move this guy
44cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      *result = std::move(*first);
45cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      ++result;
46cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    } else {
47cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      // We want to keep this guy, but we will need to move it up the list to
48ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      // replace missing items.
49ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      *new_end = std::move(*first);
50ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      ++new_end;
511ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
52cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
531ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
54ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  input_container.erase(new_end, last);
55cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return result;
561ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}
571ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
58ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinskibool PrivateAttributeMover::Consume(IAaptContext* context, ResourceTable* table) {
59cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  for (auto& package : table->packages) {
60ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ResourceTableType* type = package->FindType(ResourceType::kAttr);
61cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (!type) {
62cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      continue;
63cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    }
641ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
65ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (type->symbol_status.state != SymbolState::kPublic) {
66cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      // No public attributes, so we can safely leave these private attributes
67cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      // where they are.
68ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski      continue;
69cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    }
701ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
71ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski    std::vector<std::unique_ptr<ResourceEntry>> private_attr_entries;
721ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
73ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski    move_if(type->entries, std::back_inserter(private_attr_entries),
74ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            [](const std::unique_ptr<ResourceEntry>& entry) -> bool {
75ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski              return entry->symbol_status.state != SymbolState::kPublic;
76ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            });
77ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski
78ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski    if (private_attr_entries.empty()) {
79ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski      // No private attributes.
80ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski      continue;
81ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski    }
82ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski
83ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski    ResourceTableType* priv_attr_type = package->FindOrCreateType(ResourceType::kAttrPrivate);
84ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski    CHECK(priv_attr_type->entries.empty());
85ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski    priv_attr_type->entries = std::move(private_attr_entries);
86cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
87cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return true;
881ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}
891ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
90cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace aapt
91