1*70a7ec85SAndroid Build Coastguard Worker /* 2*70a7ec85SAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project 3*70a7ec85SAndroid Build Coastguard Worker * 4*70a7ec85SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*70a7ec85SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*70a7ec85SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*70a7ec85SAndroid Build Coastguard Worker * 8*70a7ec85SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*70a7ec85SAndroid Build Coastguard Worker * 10*70a7ec85SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*70a7ec85SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*70a7ec85SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*70a7ec85SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*70a7ec85SAndroid Build Coastguard Worker * limitations under the License. 15*70a7ec85SAndroid Build Coastguard Worker */ 16*70a7ec85SAndroid Build Coastguard Worker 17*70a7ec85SAndroid Build Coastguard Worker #ifndef ANDROID_VINTF_XML_FILE_GROUP_H 18*70a7ec85SAndroid Build Coastguard Worker #define ANDROID_VINTF_XML_FILE_GROUP_H 19*70a7ec85SAndroid Build Coastguard Worker 20*70a7ec85SAndroid Build Coastguard Worker #include <map> 21*70a7ec85SAndroid Build Coastguard Worker #include <type_traits> 22*70a7ec85SAndroid Build Coastguard Worker 23*70a7ec85SAndroid Build Coastguard Worker #include "MapValueIterator.h" 24*70a7ec85SAndroid Build Coastguard Worker #include "XmlFile.h" 25*70a7ec85SAndroid Build Coastguard Worker 26*70a7ec85SAndroid Build Coastguard Worker namespace android { 27*70a7ec85SAndroid Build Coastguard Worker namespace vintf { 28*70a7ec85SAndroid Build Coastguard Worker 29*70a7ec85SAndroid Build Coastguard Worker // A XmlFileGroup is a wrapped multimap from name to T, where T 30*70a7ec85SAndroid Build Coastguard Worker // must be a subclass of XmlFile. 31*70a7ec85SAndroid Build Coastguard Worker template <typename T> 32*70a7ec85SAndroid Build Coastguard Worker struct XmlFileGroup { 33*70a7ec85SAndroid Build Coastguard Worker static_assert(std::is_base_of<XmlFile, T>::value, "T must be a subclass of XmlFile"); 34*70a7ec85SAndroid Build Coastguard Worker 35*70a7ec85SAndroid Build Coastguard Worker private: 36*70a7ec85SAndroid Build Coastguard Worker using map = std::multimap<std::string, T>; 37*70a7ec85SAndroid Build Coastguard Worker using const_range = std::pair<typename map::const_iterator, typename map::const_iterator>; 38*70a7ec85SAndroid Build Coastguard Worker 39*70a7ec85SAndroid Build Coastguard Worker public: ~XmlFileGroupXmlFileGroup40*70a7ec85SAndroid Build Coastguard Worker virtual ~XmlFileGroup() {} 41*70a7ec85SAndroid Build Coastguard Worker addXmlFileXmlFileGroup42*70a7ec85SAndroid Build Coastguard Worker bool addXmlFile(T&& t) { 43*70a7ec85SAndroid Build Coastguard Worker if (!shouldAddXmlFile(t)) { 44*70a7ec85SAndroid Build Coastguard Worker return false; 45*70a7ec85SAndroid Build Coastguard Worker } 46*70a7ec85SAndroid Build Coastguard Worker std::string name = t.name(); 47*70a7ec85SAndroid Build Coastguard Worker mXmlFiles.emplace(std::move(name), std::move(t)); 48*70a7ec85SAndroid Build Coastguard Worker return true; 49*70a7ec85SAndroid Build Coastguard Worker } 50*70a7ec85SAndroid Build Coastguard Worker shouldAddXmlFileXmlFileGroup51*70a7ec85SAndroid Build Coastguard Worker virtual bool shouldAddXmlFile(const T&) const { return true; } 52*70a7ec85SAndroid Build Coastguard Worker getXmlFilesXmlFileGroup53*70a7ec85SAndroid Build Coastguard Worker const_range getXmlFiles(const std::string& key) const { return mXmlFiles.equal_range(key); } 54*70a7ec85SAndroid Build Coastguard Worker 55*70a7ec85SAndroid Build Coastguard Worker // Return an iterable to all T objects. Call it as follows: 56*70a7ec85SAndroid Build Coastguard Worker // for (const auto& e : vm.getXmlFiles()) { } getXmlFilesXmlFileGroup57*70a7ec85SAndroid Build Coastguard Worker ConstMultiMapValueIterable<std::string, T> getXmlFiles() const { 58*70a7ec85SAndroid Build Coastguard Worker return ConstMultiMapValueIterable<std::string, T>(mXmlFiles); 59*70a7ec85SAndroid Build Coastguard Worker } 60*70a7ec85SAndroid Build Coastguard Worker addAllXmlFilesXmlFileGroup61*70a7ec85SAndroid Build Coastguard Worker bool addAllXmlFiles(XmlFileGroup* other, std::string* error) { 62*70a7ec85SAndroid Build Coastguard Worker for (auto& pair : other->mXmlFiles) { 63*70a7ec85SAndroid Build Coastguard Worker if (!addXmlFile(std::move(pair.second))) { 64*70a7ec85SAndroid Build Coastguard Worker if (error) { 65*70a7ec85SAndroid Build Coastguard Worker *error = "XML File \"" + pair.first + "\" has a conflict."; 66*70a7ec85SAndroid Build Coastguard Worker } 67*70a7ec85SAndroid Build Coastguard Worker return false; 68*70a7ec85SAndroid Build Coastguard Worker } 69*70a7ec85SAndroid Build Coastguard Worker } 70*70a7ec85SAndroid Build Coastguard Worker other->mXmlFiles.clear(); 71*70a7ec85SAndroid Build Coastguard Worker return true; 72*70a7ec85SAndroid Build Coastguard Worker } 73*70a7ec85SAndroid Build Coastguard Worker 74*70a7ec85SAndroid Build Coastguard Worker protected: 75*70a7ec85SAndroid Build Coastguard Worker map mXmlFiles; 76*70a7ec85SAndroid Build Coastguard Worker }; 77*70a7ec85SAndroid Build Coastguard Worker 78*70a7ec85SAndroid Build Coastguard Worker } // namespace vintf 79*70a7ec85SAndroid Build Coastguard Worker } // namespace android 80*70a7ec85SAndroid Build Coastguard Worker 81*70a7ec85SAndroid Build Coastguard Worker #endif // ANDROID_VINTF_XML_FILE_GROUP_H 82