summaryrefslogtreecommitdiff
path: root/tools/aapt2/ResourceUtils.cpp
diff options
context:
space:
mode:
authorAdam Lesinski <adamlesinski@google.com>2016-07-08 15:00:32 -0700
committerAdam Lesinski <adamlesinski@google.com>2016-07-13 17:45:28 -0700
commitd0f116b619feede0cfdb647157ce5ab4d50a1c46 (patch)
tree5b2a8663602ba2b267890ff85d3cf5618ac922b5 /tools/aapt2/ResourceUtils.cpp
parentaaac91f4a00a9968ef107ea143e6f2f669f762f1 (diff)
AAPT2: Remove usage of u16string
For legacy reasons, we kept around the use of UTF-16 internally in AAPT2. We don't need this and this CL removes all instances of std::u16string and StringPiece16. The only places still needed are when interacting with the ResTable APIs that only operate in UTF16. Change-Id: I492475b84bb9014fa13bf992cff447ee7a5fe588
Diffstat (limited to 'tools/aapt2/ResourceUtils.cpp')
-rw-r--r--tools/aapt2/ResourceUtils.cpp170
1 files changed, 104 insertions, 66 deletions
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 302c04fc3780..31d6435a6184 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -27,19 +27,52 @@
namespace aapt {
namespace ResourceUtils {
-bool extractResourceName(const StringPiece16& str, StringPiece16* outPackage,
- StringPiece16* outType, StringPiece16* outEntry) {
+Maybe<ResourceName> toResourceName(const android::ResTable::resource_name& nameIn) {
+ ResourceName nameOut;
+ if (!nameIn.package) {
+ return {};
+ }
+
+ nameOut.package = util::utf16ToUtf8(StringPiece16(nameIn.package, nameIn.packageLen));
+
+ const ResourceType* type;
+ if (nameIn.type) {
+ type = parseResourceType(util::utf16ToUtf8(StringPiece16(nameIn.type, nameIn.typeLen)));
+ } else if (nameIn.type8) {
+ type = parseResourceType(StringPiece(nameIn.type8, nameIn.typeLen));
+ } else {
+ return {};
+ }
+
+ if (!type) {
+ return {};
+ }
+
+ nameOut.type = *type;
+
+ if (nameIn.name) {
+ nameOut.entry = util::utf16ToUtf8(StringPiece16(nameIn.name, nameIn.nameLen));
+ } else if (nameIn.name8) {
+ nameOut.entry = StringPiece(nameIn.name8, nameIn.nameLen).toString();
+ } else {
+ return {};
+ }
+ return nameOut;
+}
+
+bool extractResourceName(const StringPiece& str, StringPiece* outPackage,
+ StringPiece* outType, StringPiece* outEntry) {
bool hasPackageSeparator = false;
bool hasTypeSeparator = false;
- const char16_t* start = str.data();
- const char16_t* end = start + str.size();
- const char16_t* current = start;
+ const char* start = str.data();
+ const char* end = start + str.size();
+ const char* current = start;
while (current != end) {
- if (outType->size() == 0 && *current == u'/') {
+ if (outType->size() == 0 && *current == '/') {
hasTypeSeparator = true;
outType->assign(start, current - start);
start = current + 1;
- } else if (outPackage->size() == 0 && *current == u':') {
+ } else if (outPackage->size() == 0 && *current == ':') {
hasPackageSeparator = true;
outPackage->assign(start, current - start);
start = current + 1;
@@ -51,21 +84,21 @@ bool extractResourceName(const StringPiece16& str, StringPiece16* outPackage,
return !(hasPackageSeparator && outPackage->empty()) && !(hasTypeSeparator && outType->empty());
}
-bool parseResourceName(const StringPiece16& str, ResourceNameRef* outRef, bool* outPrivate) {
+bool parseResourceName(const StringPiece& str, ResourceNameRef* outRef, bool* outPrivate) {
if (str.empty()) {
return false;
}
size_t offset = 0;
bool priv = false;
- if (str.data()[0] == u'*') {
+ if (str.data()[0] == '*') {
priv = true;
offset = 1;
}
- StringPiece16 package;
- StringPiece16 type;
- StringPiece16 entry;
+ StringPiece package;
+ StringPiece type;
+ StringPiece entry;
if (!extractResourceName(str.substr(offset, str.size() - offset), &package, &type, &entry)) {
return false;
}
@@ -91,18 +124,18 @@ bool parseResourceName(const StringPiece16& str, ResourceNameRef* outRef, bool*
return true;
}
-bool tryParseReference(const StringPiece16& str, ResourceNameRef* outRef, bool* outCreate,
+bool tryParseReference(const StringPiece& str, ResourceNameRef* outRef, bool* outCreate,
bool* outPrivate) {
- StringPiece16 trimmedStr(util::trimWhitespace(str));
+ StringPiece trimmedStr(util::trimWhitespace(str));
if (trimmedStr.empty()) {
return false;
}
bool create = false;
bool priv = false;
- if (trimmedStr.data()[0] == u'@') {
+ if (trimmedStr.data()[0] == '@') {
size_t offset = 1;
- if (trimmedStr.data()[1] == u'+') {
+ if (trimmedStr.data()[1] == '+') {
create = true;
offset += 1;
}
@@ -137,26 +170,26 @@ bool tryParseReference(const StringPiece16& str, ResourceNameRef* outRef, bool*
return false;
}
-bool isReference(const StringPiece16& str) {
+bool isReference(const StringPiece& str) {
return tryParseReference(str, nullptr, nullptr, nullptr);
}
-bool tryParseAttributeReference(const StringPiece16& str, ResourceNameRef* outRef) {
- StringPiece16 trimmedStr(util::trimWhitespace(str));
+bool tryParseAttributeReference(const StringPiece& str, ResourceNameRef* outRef) {
+ StringPiece trimmedStr(util::trimWhitespace(str));
if (trimmedStr.empty()) {
return false;
}
- if (*trimmedStr.data() == u'?') {
- StringPiece16 package;
- StringPiece16 type;
- StringPiece16 entry;
+ if (*trimmedStr.data() == '?') {
+ StringPiece package;
+ StringPiece type;
+ StringPiece entry;
if (!extractResourceName(trimmedStr.substr(1, trimmedStr.size() - 1),
&package, &type, &entry)) {
return false;
}
- if (!type.empty() && type != u"attr") {
+ if (!type.empty() && type != "attr") {
return false;
}
@@ -174,7 +207,7 @@ bool tryParseAttributeReference(const StringPiece16& str, ResourceNameRef* outRe
return false;
}
-bool isAttributeReference(const StringPiece16& str) {
+bool isAttributeReference(const StringPiece& str) {
return tryParseAttributeReference(str, nullptr);
}
@@ -186,23 +219,23 @@ bool isAttributeReference(const StringPiece16& str) {
* <[*]package>:[style/]<entry>
* [[*]package:style/]<entry>
*/
-Maybe<Reference> parseStyleParentReference(const StringPiece16& str, std::string* outError) {
+Maybe<Reference> parseStyleParentReference(const StringPiece& str, std::string* outError) {
if (str.empty()) {
return {};
}
- StringPiece16 name = str;
+ StringPiece name = str;
bool hasLeadingIdentifiers = false;
bool privateRef = false;
// Skip over these identifiers. A style's parent is a normal reference.
- if (name.data()[0] == u'@' || name.data()[0] == u'?') {
+ if (name.data()[0] == '@' || name.data()[0] == '?') {
hasLeadingIdentifiers = true;
name = name.substr(1, name.size() - 1);
}
- if (name.data()[0] == u'*') {
+ if (name.data()[0] == '*') {
privateRef = true;
name = name.substr(1, name.size() - 1);
}
@@ -210,7 +243,7 @@ Maybe<Reference> parseStyleParentReference(const StringPiece16& str, std::string
ResourceNameRef ref;
ref.type = ResourceType::kStyle;
- StringPiece16 typeStr;
+ StringPiece typeStr;
extractResourceName(name, &ref.package, &typeStr, &ref.entry);
if (!typeStr.empty()) {
// If we have a type, make sure it is a Style.
@@ -235,7 +268,7 @@ Maybe<Reference> parseStyleParentReference(const StringPiece16& str, std::string
return result;
}
-std::unique_ptr<Reference> tryParseReference(const StringPiece16& str, bool* outCreate) {
+std::unique_ptr<Reference> tryParseReference(const StringPiece& str, bool* outCreate) {
ResourceNameRef ref;
bool privateRef = false;
if (tryParseReference(str, &ref, outCreate, &privateRef)) {
@@ -253,14 +286,14 @@ std::unique_ptr<Reference> tryParseReference(const StringPiece16& str, bool* out
return {};
}
-std::unique_ptr<BinaryPrimitive> tryParseNullOrEmpty(const StringPiece16& str) {
- StringPiece16 trimmedStr(util::trimWhitespace(str));
+std::unique_ptr<BinaryPrimitive> tryParseNullOrEmpty(const StringPiece& str) {
+ StringPiece trimmedStr(util::trimWhitespace(str));
android::Res_value value = { };
- if (trimmedStr == u"@null") {
+ if (trimmedStr == "@null") {
// TYPE_NULL with data set to 0 is interpreted by the runtime as an error.
// Instead we set the data type to TYPE_REFERENCE with a value of 0.
value.dataType = android::Res_value::TYPE_REFERENCE;
- } else if (trimmedStr == u"@empty") {
+ } else if (trimmedStr == "@empty") {
// TYPE_NULL with value of DATA_NULL_EMPTY is handled fine by the runtime.
value.dataType = android::Res_value::TYPE_NULL;
value.data = android::Res_value::DATA_NULL_EMPTY;
@@ -271,8 +304,8 @@ std::unique_ptr<BinaryPrimitive> tryParseNullOrEmpty(const StringPiece16& str) {
}
std::unique_ptr<BinaryPrimitive> tryParseEnumSymbol(const Attribute* enumAttr,
- const StringPiece16& str) {
- StringPiece16 trimmedStr(util::trimWhitespace(str));
+ const StringPiece& str) {
+ StringPiece trimmedStr(util::trimWhitespace(str));
for (const Attribute::Symbol& symbol : enumAttr->symbols) {
// Enum symbols are stored as @package:id/symbol resources,
// so we need to match against the 'entry' part of the identifier.
@@ -288,7 +321,7 @@ std::unique_ptr<BinaryPrimitive> tryParseEnumSymbol(const Attribute* enumAttr,
}
std::unique_ptr<BinaryPrimitive> tryParseFlagSymbol(const Attribute* flagAttr,
- const StringPiece16& str) {
+ const StringPiece& str) {
android::Res_value flags = { };
flags.dataType = android::Res_value::TYPE_INT_HEX;
flags.data = 0u;
@@ -298,8 +331,8 @@ std::unique_ptr<BinaryPrimitive> tryParseFlagSymbol(const Attribute* flagAttr,
return util::make_unique<BinaryPrimitive>(flags);
}
- for (StringPiece16 part : util::tokenize(str, u'|')) {
- StringPiece16 trimmedPart = util::trimWhitespace(part);
+ for (StringPiece part : util::tokenize(str, '|')) {
+ StringPiece trimmedPart = util::trimWhitespace(part);
bool flagSet = false;
for (const Attribute::Symbol& symbol : flagAttr->symbols) {
@@ -320,24 +353,24 @@ std::unique_ptr<BinaryPrimitive> tryParseFlagSymbol(const Attribute* flagAttr,
return util::make_unique<BinaryPrimitive>(flags);
}
-static uint32_t parseHex(char16_t c, bool* outError) {
- if (c >= u'0' && c <= u'9') {
- return c - u'0';
- } else if (c >= u'a' && c <= u'f') {
- return c - u'a' + 0xa;
- } else if (c >= u'A' && c <= u'F') {
- return c - u'A' + 0xa;
+static uint32_t parseHex(char c, bool* outError) {
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ } else if (c >= 'a' && c <= 'f') {
+ return c - 'a' + 0xa;
+ } else if (c >= 'A' && c <= 'F') {
+ return c - 'A' + 0xa;
} else {
*outError = true;
return 0xffffffffu;
}
}
-std::unique_ptr<BinaryPrimitive> tryParseColor(const StringPiece16& str) {
- StringPiece16 colorStr(util::trimWhitespace(str));
- const char16_t* start = colorStr.data();
+std::unique_ptr<BinaryPrimitive> tryParseColor(const StringPiece& str) {
+ StringPiece colorStr(util::trimWhitespace(str));
+ const char* start = colorStr.data();
const size_t len = colorStr.size();
- if (len == 0 || start[0] != u'#') {
+ if (len == 0 || start[0] != '#') {
return {};
}
@@ -387,14 +420,14 @@ std::unique_ptr<BinaryPrimitive> tryParseColor(const StringPiece16& str) {
return error ? std::unique_ptr<BinaryPrimitive>() : util::make_unique<BinaryPrimitive>(value);
}
-bool tryParseBool(const StringPiece16& str, bool* outValue) {
- StringPiece16 trimmedStr(util::trimWhitespace(str));
- if (trimmedStr == u"true" || trimmedStr == u"TRUE" || trimmedStr == u"True") {
+bool tryParseBool(const StringPiece& str, bool* outValue) {
+ StringPiece trimmedStr(util::trimWhitespace(str));
+ if (trimmedStr == "true" || trimmedStr == "TRUE" || trimmedStr == "True") {
if (outValue) {
*outValue = true;
}
return true;
- } else if (trimmedStr == u"false" || trimmedStr == u"FALSE" || trimmedStr == u"False") {
+ } else if (trimmedStr == "false" || trimmedStr == "FALSE" || trimmedStr == "False") {
if (outValue) {
*outValue = false;
}
@@ -403,22 +436,24 @@ bool tryParseBool(const StringPiece16& str, bool* outValue) {
return false;
}
-Maybe<int> tryParseSdkVersion(const StringPiece16& str) {
- StringPiece16 trimmedStr(util::trimWhitespace(str));
+Maybe<int> tryParseSdkVersion(const StringPiece& str) {
+ StringPiece trimmedStr(util::trimWhitespace(str));
+
+ std::u16string str16 = util::utf8ToUtf16(trimmedStr);
android::Res_value value;
- if (android::ResTable::stringToInt(trimmedStr.data(), trimmedStr.size(), &value)) {
+ if (android::ResTable::stringToInt(str16.data(), str16.size(), &value)) {
return static_cast<int>(value.data);
}
// Try parsing the code name.
- std::pair<StringPiece16, int> entry = getDevelopmentSdkCodeNameAndVersion();
+ std::pair<StringPiece, int> entry = getDevelopmentSdkCodeNameAndVersion();
if (entry.first == trimmedStr) {
return entry.second;
}
return {};
}
-std::unique_ptr<BinaryPrimitive> tryParseBool(const StringPiece16& str) {
+std::unique_ptr<BinaryPrimitive> tryParseBool(const StringPiece& str) {
bool result = false;
if (tryParseBool(str, &result)) {
android::Res_value value = {};
@@ -434,17 +469,19 @@ std::unique_ptr<BinaryPrimitive> tryParseBool(const StringPiece16& str) {
return {};
}
-std::unique_ptr<BinaryPrimitive> tryParseInt(const StringPiece16& str) {
+std::unique_ptr<BinaryPrimitive> tryParseInt(const StringPiece& str) {
+ std::u16string str16 = util::utf8ToUtf16(str);
android::Res_value value;
- if (!android::ResTable::stringToInt(str.data(), str.size(), &value)) {
+ if (!android::ResTable::stringToInt(str16.data(), str16.size(), &value)) {
return {};
}
return util::make_unique<BinaryPrimitive>(value);
}
-std::unique_ptr<BinaryPrimitive> tryParseFloat(const StringPiece16& str) {
+std::unique_ptr<BinaryPrimitive> tryParseFloat(const StringPiece& str) {
+ std::u16string str16 = util::utf8ToUtf16(str);
android::Res_value value;
- if (!android::ResTable::stringToFloat(str.data(), str.size(), &value)) {
+ if (!android::ResTable::stringToFloat(str16.data(), str16.size(), &value)) {
return {};
}
return util::make_unique<BinaryPrimitive>(value);
@@ -490,7 +527,8 @@ uint32_t androidTypeToAttributeTypeMask(uint16_t type) {
}
std::unique_ptr<Item> parseItemForAttribute(
- const StringPiece16& value, uint32_t typeMask,
+ const StringPiece& value,
+ uint32_t typeMask,
std::function<void(const ResourceName&)> onCreateReference) {
std::unique_ptr<BinaryPrimitive> nullOrEmpty = tryParseNullOrEmpty(value);
if (nullOrEmpty) {
@@ -549,7 +587,7 @@ std::unique_ptr<Item> parseItemForAttribute(
* allows.
*/
std::unique_ptr<Item> parseItemForAttribute(
- const StringPiece16& str, const Attribute* attr,
+ const StringPiece& str, const Attribute* attr,
std::function<void(const ResourceName&)> onCreateReference) {
const uint32_t typeMask = attr->typeMask;
std::unique_ptr<Item> value = parseItemForAttribute(str, typeMask, onCreateReference);