Adam Lesinski 9ba47d8130 Filter products during compile phase
Unfortunately there is no good way to deal with products in the link phase.
Products are like preprocessor defines in that they are processed early
and change the composition of the compiled unit.

Change-Id: I6d5e15ef60d29df8e83e059ba857c09333993779
2015-10-16 15:50:58 -07:00

332 lines
8.4 KiB
C++

/*
* Copyright (C) 2015 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 AAPT_RESOURCE_H
#define AAPT_RESOURCE_H
#include "ConfigDescription.h"
#include "Source.h"
#include "util/StringPiece.h"
#include <iomanip>
#include <limits>
#include <string>
#include <tuple>
#include <vector>
namespace aapt {
/**
* The various types of resource types available. Corresponds
* to the 'type' in package:type/entry.
*/
enum class ResourceType {
kAnim,
kAnimator,
kArray,
kAttr,
kAttrPrivate,
kBool,
kColor,
kDimen,
kDrawable,
kFraction,
kId,
kInteger,
kIntegerArray,
kInterpolator,
kLayout,
kMenu,
kMipmap,
kPlurals,
kRaw,
kString,
kStyle,
kStyleable,
kTransition,
kXml,
};
StringPiece16 toString(ResourceType type);
/**
* Returns a pointer to a valid ResourceType, or nullptr if
* the string was invalid.
*/
const ResourceType* parseResourceType(const StringPiece16& str);
/**
* A resource's name. This can uniquely identify
* a resource in the ResourceTable.
*/
struct ResourceName {
std::u16string package;
ResourceType type;
std::u16string entry;
ResourceName() = default;
ResourceName(const StringPiece16& p, ResourceType t, const StringPiece16& e);
bool isValid() const;
bool operator<(const ResourceName& rhs) const;
bool operator==(const ResourceName& rhs) const;
bool operator!=(const ResourceName& rhs) const;
std::u16string toString() const;
};
/**
* Same as ResourceName, but uses StringPieces instead.
* Use this if you need to avoid copying and know that
* the lifetime of this object is shorter than that
* of the original string.
*/
struct ResourceNameRef {
StringPiece16 package;
ResourceType type;
StringPiece16 entry;
ResourceNameRef() = default;
ResourceNameRef(const ResourceNameRef&) = default;
ResourceNameRef(ResourceNameRef&&) = default;
ResourceNameRef(const ResourceName& rhs);
ResourceNameRef(const StringPiece16& p, ResourceType t, const StringPiece16& e);
ResourceNameRef& operator=(const ResourceNameRef& rhs) = default;
ResourceNameRef& operator=(ResourceNameRef&& rhs) = default;
ResourceNameRef& operator=(const ResourceName& rhs);
ResourceName toResourceName() const;
bool isValid() const;
bool operator<(const ResourceNameRef& rhs) const;
bool operator==(const ResourceNameRef& rhs) const;
bool operator!=(const ResourceNameRef& rhs) const;
};
/**
* A binary identifier representing a resource. Internally it
* is a 32bit integer split as follows:
*
* 0xPPTTEEEE
*
* PP: 8 bit package identifier. 0x01 is reserved for system
* and 0x7f is reserved for the running app.
* TT: 8 bit type identifier. 0x00 is invalid.
* EEEE: 16 bit entry identifier.
*/
struct ResourceId {
uint32_t id;
ResourceId();
ResourceId(const ResourceId& rhs);
ResourceId(uint32_t resId);
ResourceId(uint8_t p, uint8_t t, uint16_t e);
bool isValid() const;
uint8_t packageId() const;
uint8_t typeId() const;
uint16_t entryId() const;
bool operator<(const ResourceId& rhs) const;
bool operator==(const ResourceId& rhs) const;
};
struct SourcedResourceName {
ResourceName name;
size_t line;
inline bool operator==(const SourcedResourceName& rhs) const {
return name == rhs.name && line == rhs.line;
}
};
struct ResourceFile {
// Name
ResourceName name;
// Configuration
ConfigDescription config;
// Source
Source source;
// Exported symbols
std::vector<SourcedResourceName> exportedSymbols;
};
//
// ResourceId implementation.
//
inline ResourceId::ResourceId() : id(0) {
}
inline ResourceId::ResourceId(const ResourceId& rhs) : id(rhs.id) {
}
inline ResourceId::ResourceId(uint32_t resId) : id(resId) {
}
inline ResourceId::ResourceId(uint8_t p, uint8_t t, uint16_t e) : id((p << 24) | (t << 16) | e) {
}
inline bool ResourceId::isValid() const {
return (id & 0xff000000u) != 0 && (id & 0x00ff0000u) != 0;
}
inline uint8_t ResourceId::packageId() const {
return static_cast<uint8_t>(id >> 24);
}
inline uint8_t ResourceId::typeId() const {
return static_cast<uint8_t>(id >> 16);
}
inline uint16_t ResourceId::entryId() const {
return static_cast<uint16_t>(id);
}
inline bool ResourceId::operator<(const ResourceId& rhs) const {
return id < rhs.id;
}
inline bool ResourceId::operator==(const ResourceId& rhs) const {
return id == rhs.id;
}
inline ::std::ostream& operator<<(::std::ostream& out,
const ResourceId& resId) {
std::ios_base::fmtflags oldFlags = out.flags();
char oldFill = out.fill();
out << "0x" << std::internal << std::setfill('0') << std::setw(8)
<< std::hex << resId.id;
out.flags(oldFlags);
out.fill(oldFill);
return out;
}
//
// ResourceType implementation.
//
inline ::std::ostream& operator<<(::std::ostream& out, const ResourceType& val) {
return out << toString(val);
}
//
// ResourceName implementation.
//
inline ResourceName::ResourceName(const StringPiece16& p, ResourceType t, const StringPiece16& e) :
package(p.toString()), type(t), entry(e.toString()) {
}
inline bool ResourceName::isValid() const {
return !package.empty() && !entry.empty();
}
inline bool ResourceName::operator<(const ResourceName& rhs) const {
return std::tie(package, type, entry)
< std::tie(rhs.package, rhs.type, rhs.entry);
}
inline bool operator<(const ResourceName& lhs, const ResourceNameRef& b) {
return ResourceNameRef(lhs) < b;
}
inline bool ResourceName::operator==(const ResourceName& rhs) const {
return std::tie(package, type, entry)
== std::tie(rhs.package, rhs.type, rhs.entry);
}
inline bool ResourceName::operator!=(const ResourceName& rhs) const {
return std::tie(package, type, entry)
!= std::tie(rhs.package, rhs.type, rhs.entry);
}
inline bool operator!=(const ResourceName& lhs, const ResourceNameRef& rhs) {
return ResourceNameRef(lhs) != rhs;
}
inline std::u16string ResourceName::toString() const {
std::u16string result;
if (!package.empty()) {
result = package + u":";
}
return result + aapt::toString(type).toString() + u"/" + entry;
}
inline ::std::ostream& operator<<(::std::ostream& out, const ResourceName& name) {
if (!name.package.empty()) {
out << name.package << ":";
}
return out << name.type << "/" << name.entry;
}
//
// ResourceNameRef implementation.
//
inline ResourceNameRef::ResourceNameRef(const ResourceName& rhs) :
package(rhs.package), type(rhs.type), entry(rhs.entry) {
}
inline ResourceNameRef::ResourceNameRef(const StringPiece16& p, ResourceType t,
const StringPiece16& e) :
package(p), type(t), entry(e) {
}
inline ResourceNameRef& ResourceNameRef::operator=(const ResourceName& rhs) {
package = rhs.package;
type = rhs.type;
entry = rhs.entry;
return *this;
}
inline ResourceName ResourceNameRef::toResourceName() const {
return { package.toString(), type, entry.toString() };
}
inline bool ResourceNameRef::isValid() const {
return !package.empty() && !entry.empty();
}
inline bool ResourceNameRef::operator<(const ResourceNameRef& rhs) const {
return std::tie(package, type, entry)
< std::tie(rhs.package, rhs.type, rhs.entry);
}
inline bool ResourceNameRef::operator==(const ResourceNameRef& rhs) const {
return std::tie(package, type, entry)
== std::tie(rhs.package, rhs.type, rhs.entry);
}
inline bool ResourceNameRef::operator!=(const ResourceNameRef& rhs) const {
return std::tie(package, type, entry)
!= std::tie(rhs.package, rhs.type, rhs.entry);
}
inline ::std::ostream& operator<<(::std::ostream& out, const ResourceNameRef& name) {
if (!name.package.empty()) {
out << name.package << ":";
}
return out << name.type << "/" << name.entry;
}
} // namespace aapt
#endif // AAPT_RESOURCE_H