Introduce ResourceNamedType that represents pair of name + ResourceType.
This type will be used as part of ResourceName to support types with custom names inside aapt2. DD: go/custom-resource-types-in-aapt2 Bug: b/215108200 Test: Resource_test.cpp Change-Id: Ib09776e6b2f69fefb9724136a345dc25bea42573
This commit is contained in:
@@ -134,6 +134,24 @@ static const std::map<StringPiece, ResourceType> sResourceTypeMap{
|
||||
{"xml", ResourceType::kXml},
|
||||
};
|
||||
|
||||
ResourceNamedTypeRef ResourceNamedTypeWithDefaultName(ResourceType t) {
|
||||
return {to_string(t), t};
|
||||
}
|
||||
|
||||
std::optional<ResourceNamedTypeRef> ParseResourceNamedType(const android::StringPiece& s) {
|
||||
auto colon = std::find(s.begin(), s.end(), ':');
|
||||
const ResourceType* parsedType;
|
||||
if (colon != s.end() && colon != std::prev(s.end())) {
|
||||
parsedType = ParseResourceType(s.substr(s.begin(), colon));
|
||||
} else {
|
||||
parsedType = ParseResourceType(s);
|
||||
}
|
||||
if (parsedType == nullptr) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return ResourceNamedTypeRef(s, *parsedType);
|
||||
}
|
||||
|
||||
const ResourceType* ParseResourceType(const StringPiece& str) {
|
||||
auto iter = sResourceTypeMap.find(str);
|
||||
if (iter == std::end(sResourceTypeMap)) {
|
||||
|
||||
@@ -19,22 +19,21 @@
|
||||
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "Source.h"
|
||||
#include "androidfw/ConfigDescription.h"
|
||||
#include "androidfw/StringPiece.h"
|
||||
#include "utils/JenkinsHash.h"
|
||||
|
||||
#include "Source.h"
|
||||
|
||||
namespace aapt {
|
||||
|
||||
/**
|
||||
* The various types of resource types available. Corresponds
|
||||
* to the 'type' in package:type/entry.
|
||||
* The various types of resource types available.
|
||||
*/
|
||||
enum class ResourceType {
|
||||
kAnim,
|
||||
@@ -77,6 +76,52 @@ android::StringPiece to_string(ResourceType type);
|
||||
*/
|
||||
const ResourceType* ParseResourceType(const android::StringPiece& str);
|
||||
|
||||
/**
|
||||
* Pair of type name as in ResourceTable and actual resource type.
|
||||
* Corresponds to the 'type' in package:type/entry.
|
||||
*
|
||||
* This is to support resource types with custom names inside resource tables.
|
||||
*/
|
||||
struct ResourceNamedType {
|
||||
std::string name;
|
||||
ResourceType type = ResourceType::kRaw;
|
||||
|
||||
ResourceNamedType() = default;
|
||||
ResourceNamedType(const android::StringPiece& n, ResourceType t);
|
||||
|
||||
int compare(const ResourceNamedType& other) const;
|
||||
|
||||
const std::string& to_string() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Same as ResourceNamedType, 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 ResourceNamedTypeRef {
|
||||
android::StringPiece name;
|
||||
ResourceType type = ResourceType::kRaw;
|
||||
|
||||
ResourceNamedTypeRef() = default;
|
||||
ResourceNamedTypeRef(const ResourceNamedTypeRef&) = default;
|
||||
ResourceNamedTypeRef(ResourceNamedTypeRef&&) = default;
|
||||
ResourceNamedTypeRef(const ResourceNamedType& rhs); // NOLINT(google-explicit-constructor)
|
||||
ResourceNamedTypeRef(const android::StringPiece& n, ResourceType t);
|
||||
ResourceNamedTypeRef& operator=(const ResourceNamedTypeRef& rhs) = default;
|
||||
ResourceNamedTypeRef& operator=(ResourceNamedTypeRef&& rhs) = default;
|
||||
ResourceNamedTypeRef& operator=(const ResourceNamedType& rhs);
|
||||
|
||||
ResourceNamedType ToResourceNamedType() const;
|
||||
|
||||
std::string to_string() const;
|
||||
};
|
||||
|
||||
ResourceNamedTypeRef ResourceNamedTypeWithDefaultName(ResourceType t);
|
||||
|
||||
std::optional<ResourceNamedTypeRef> ParseResourceNamedType(const android::StringPiece& s);
|
||||
|
||||
/**
|
||||
* A resource's name. This can uniquely identify
|
||||
* a resource in the ResourceTable.
|
||||
@@ -294,6 +339,81 @@ inline ::std::ostream& operator<<(::std::ostream& out, const ResourceType& val)
|
||||
return out << to_string(val);
|
||||
}
|
||||
|
||||
//
|
||||
// ResourceNamedType implementation.
|
||||
//
|
||||
inline ResourceNamedType::ResourceNamedType(const android::StringPiece& n, ResourceType t)
|
||||
: name(n.to_string()), type(t) {
|
||||
}
|
||||
|
||||
inline int ResourceNamedType::compare(const ResourceNamedType& other) const {
|
||||
int cmp = static_cast<int>(type) - static_cast<int>(other.type);
|
||||
if (cmp != 0) return cmp;
|
||||
cmp = name.compare(other.name);
|
||||
return cmp;
|
||||
}
|
||||
|
||||
inline const std::string& ResourceNamedType::to_string() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
inline bool operator<(const ResourceNamedType& lhs, const ResourceNamedType& rhs) {
|
||||
return lhs.compare(rhs) < 0;
|
||||
}
|
||||
|
||||
inline bool operator==(const ResourceNamedType& lhs, const ResourceNamedType& rhs) {
|
||||
return lhs.compare(rhs) == 0;
|
||||
}
|
||||
|
||||
inline bool operator!=(const ResourceNamedType& lhs, const ResourceNamedType& rhs) {
|
||||
return lhs.compare(rhs) != 0;
|
||||
}
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& out, const ResourceNamedType& val) {
|
||||
return out << val.to_string();
|
||||
}
|
||||
|
||||
//
|
||||
// ResourceNamedTypeRef implementation.
|
||||
//
|
||||
inline ResourceNamedTypeRef::ResourceNamedTypeRef(const android::StringPiece& n, ResourceType t)
|
||||
: name(n), type(t) {
|
||||
}
|
||||
|
||||
inline ResourceNamedTypeRef::ResourceNamedTypeRef(const ResourceNamedType& rhs)
|
||||
: name(rhs.name), type(rhs.type) {
|
||||
}
|
||||
|
||||
inline ResourceNamedTypeRef& ResourceNamedTypeRef::operator=(const ResourceNamedType& rhs) {
|
||||
name = rhs.name;
|
||||
type = rhs.type;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline ResourceNamedType ResourceNamedTypeRef::ToResourceNamedType() const {
|
||||
return ResourceNamedType(name, type);
|
||||
}
|
||||
|
||||
inline std::string ResourceNamedTypeRef::to_string() const {
|
||||
return name.to_string();
|
||||
}
|
||||
|
||||
inline bool operator<(const ResourceNamedTypeRef& lhs, const ResourceNamedTypeRef& rhs) {
|
||||
return std::tie(lhs.type, lhs.name) < std::tie(rhs.type, rhs.name);
|
||||
}
|
||||
|
||||
inline bool operator==(const ResourceNamedTypeRef& lhs, const ResourceNamedTypeRef& rhs) {
|
||||
return std::tie(lhs.type, lhs.name) == std::tie(rhs.type, rhs.name);
|
||||
}
|
||||
|
||||
inline bool operator!=(const ResourceNamedTypeRef& lhs, const ResourceNamedTypeRef& rhs) {
|
||||
return std::tie(lhs.type, lhs.name) != std::tie(rhs.type, rhs.name);
|
||||
}
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& out, const ResourceNamedTypeRef& val) {
|
||||
return out << val.name;
|
||||
}
|
||||
|
||||
//
|
||||
// ResourceName implementation.
|
||||
//
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
|
||||
#include "test/Test.h"
|
||||
|
||||
using ::testing::Eq;
|
||||
using ::testing::Optional;
|
||||
|
||||
namespace aapt {
|
||||
|
||||
TEST(ResourceTypeTest, ParseResourceTypes) {
|
||||
@@ -125,4 +128,104 @@ TEST(ResourceTypeTest, ParseResourceTypes) {
|
||||
EXPECT_EQ(type, nullptr);
|
||||
}
|
||||
|
||||
TEST(ResourceTypeTest, ParseResourceNamedType) {
|
||||
auto type = ParseResourceNamedType("anim");
|
||||
EXPECT_THAT(type, Optional(Eq(ResourceNamedType("anim", ResourceType::kAnim))));
|
||||
|
||||
type = ParseResourceNamedType("layout");
|
||||
EXPECT_THAT(type, Optional(Eq(ResourceNamedType("layout", ResourceType::kLayout))));
|
||||
|
||||
type = ParseResourceNamedType("layout:2");
|
||||
EXPECT_THAT(type, Optional(Eq(ResourceNamedType("layout:2", ResourceType::kLayout))));
|
||||
|
||||
type = ParseResourceNamedType("layout:another");
|
||||
EXPECT_THAT(type, Optional(Eq(ResourceNamedType("layout:another", ResourceType::kLayout))));
|
||||
|
||||
type = ParseResourceNamedType("layout:");
|
||||
EXPECT_THAT(type, Eq(std::nullopt));
|
||||
|
||||
type = ParseResourceNamedType("layout2");
|
||||
EXPECT_THAT(type, Eq(std::nullopt));
|
||||
|
||||
type = ParseResourceNamedType("blahaha");
|
||||
EXPECT_THAT(type, Eq(std::nullopt));
|
||||
}
|
||||
|
||||
TEST(ResourceTypeTest, ResourceNamedTypeWithDefaultName) {
|
||||
auto type = ResourceNamedTypeWithDefaultName(ResourceType::kAnim);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("anim", ResourceType::kAnim)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kAnimator);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("animator", ResourceType::kAnimator)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kArray);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("array", ResourceType::kArray)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kAttr);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("attr", ResourceType::kAttr)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kAttrPrivate);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("^attr-private", ResourceType::kAttrPrivate)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kBool);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("bool", ResourceType::kBool)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kColor);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("color", ResourceType::kColor)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kConfigVarying);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("configVarying", ResourceType::kConfigVarying)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kDimen);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("dimen", ResourceType::kDimen)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kDrawable);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("drawable", ResourceType::kDrawable)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kFont);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("font", ResourceType::kFont)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kFraction);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("fraction", ResourceType::kFraction)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kId);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("id", ResourceType::kId)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kInteger);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("integer", ResourceType::kInteger)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kInterpolator);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("interpolator", ResourceType::kInterpolator)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kLayout);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("layout", ResourceType::kLayout)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kMenu);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("menu", ResourceType::kMenu)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kMipmap);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("mipmap", ResourceType::kMipmap)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kNavigation);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("navigation", ResourceType::kNavigation)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kPlurals);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("plurals", ResourceType::kPlurals)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kRaw);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("raw", ResourceType::kRaw)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kString);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("string", ResourceType::kString)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kStyle);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("style", ResourceType::kStyle)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kTransition);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("transition", ResourceType::kTransition)));
|
||||
|
||||
type = ResourceNamedTypeWithDefaultName(ResourceType::kXml);
|
||||
EXPECT_THAT(type, Eq(ResourceNamedType("xml", ResourceType::kXml)));
|
||||
}
|
||||
|
||||
} // namespace aapt
|
||||
|
||||
Reference in New Issue
Block a user