Merge "AAPT2: Enable windows build and make sure it builds" into nyc-dev

This commit is contained in:
Adam Lesinski
2016-04-07 17:03:54 +00:00
committed by Android (Google) Code Review
17 changed files with 133 additions and 86 deletions

View File

@@ -131,33 +131,40 @@ hostStaticLibs := \
libbase \ libbase \
libprotobuf-cpp-lite_static libprotobuf-cpp-lite_static
# Do not add any shared libraries. AAPT2 is built to run on many
# environments that may not have the required dependencies.
hostSharedLibs :=
ifneq ($(strip $(USE_MINGW)),) # Statically link libz for MinGW (Win SDK under Linux),
hostStaticLibs += libz # and dynamically link for all others.
else hostStaticLibs_windows := libz
hostLdLibs += -lz hostLdLibs_linux := -lz
endif hostLdLibs_darwin := -lz
cFlags := -Wall -Werror -Wno-unused-parameter -UNDEBUG cFlags := -Wall -Werror -Wno-unused-parameter -UNDEBUG
cppFlags := -std=c++14 -Wno-missing-field-initializers -fno-exceptions -fno-rtti cFlags_darwin := -D_DARWIN_UNLIMITED_STREAMS
cFlags_windows := -Wno-maybe-uninitialized # Incorrectly marking use of Maybe.value() as error.
cppFlags := -std=c++11 -Wno-missing-field-initializers -fno-exceptions -fno-rtti
protoIncludes := $(call generated-sources-dir-for,STATIC_LIBRARIES,libaapt2,HOST) protoIncludes := $(call generated-sources-dir-for,STATIC_LIBRARIES,libaapt2,HOST)
# ==========================================================
# NOTE: Do not add any shared libraries.
# AAPT2 is built to run on many environments
# that may not have the required dependencies.
# ==========================================================
# ========================================================== # ==========================================================
# Build the host static library: libaapt2 # Build the host static library: libaapt2
# ========================================================== # ==========================================================
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE := libaapt2 LOCAL_MODULE := libaapt2
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_CFLAGS := $(cFlags)
LOCAL_CFLAGS_darwin := $(cFlags_darwin)
LOCAL_CFLAGS_windows := $(cFlags_windows)
LOCAL_CPPFLAGS := $(cppFlags)
LOCAL_C_INCLUDES := $(protoIncludes)
LOCAL_SRC_FILES := $(sources) LOCAL_SRC_FILES := $(sources)
LOCAL_STATIC_LIBRARIES += $(hostStaticLibs) LOCAL_STATIC_LIBRARIES := $(hostStaticLibs)
LOCAL_CFLAGS += $(cFlags) LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
LOCAL_CPPFLAGS += $(cppFlags)
LOCAL_C_INCLUDES += $(protoIncludes)
include $(BUILD_HOST_STATIC_LIBRARY) include $(BUILD_HOST_STATIC_LIBRARY)
# ========================================================== # ==========================================================
@@ -166,16 +173,18 @@ include $(BUILD_HOST_STATIC_LIBRARY)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := libaapt2_tests LOCAL_MODULE := libaapt2_tests
LOCAL_MODULE_TAGS := tests LOCAL_MODULE_TAGS := tests
LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_CFLAGS := $(cFlags)
LOCAL_CFLAGS_darwin := $(cFlags_darwin)
LOCAL_CFLAGS_windows := $(cFlags_windows)
LOCAL_CPPFLAGS := $(cppFlags)
LOCAL_C_INCLUDES := $(protoIncludes)
LOCAL_SRC_FILES := $(testSources) LOCAL_SRC_FILES := $(testSources)
LOCAL_STATIC_LIBRARIES := libaapt2 $(hostStaticLibs)
LOCAL_STATIC_LIBRARIES += libaapt2 $(hostStaticLibs) LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
LOCAL_SHARED_LIBRARIES += $(hostSharedLibs) LOCAL_LDLIBS := $(hostLdLibs)
LOCAL_LDLIBS += $(hostLdLibs) LOCAL_LDLIBS_darwin := $(hostLdLibs_darwin)
LOCAL_CFLAGS += $(cFlags) LOCAL_LDLIBS_linux := $(hostLdLibs_linux)
LOCAL_CPPFLAGS += $(cppFlags)
LOCAL_C_INCLUDES += $(protoIncludes)
include $(BUILD_HOST_NATIVE_TEST) include $(BUILD_HOST_NATIVE_TEST)
# ========================================================== # ==========================================================
@@ -183,16 +192,18 @@ include $(BUILD_HOST_NATIVE_TEST)
# ========================================================== # ==========================================================
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := aapt2 LOCAL_MODULE := aapt2
LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_CFLAGS := $(cFlags)
LOCAL_CFLAGS_darwin := $(cFlags_darwin)
LOCAL_CFLAGS_windows := $(cFlags_windows)
LOCAL_CPPFLAGS := $(cppFlags)
LOCAL_C_INCLUDES := $(protoIncludes)
LOCAL_SRC_FILES := $(main) $(toolSources) LOCAL_SRC_FILES := $(main) $(toolSources)
LOCAL_STATIC_LIBRARIES := libaapt2 $(hostStaticLibs)
LOCAL_STATIC_LIBRARIES += libaapt2 $(hostStaticLibs) LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
LOCAL_SHARED_LIBRARIES += $(hostSharedLibs) LOCAL_LDLIBS := $(hostLdLibs)
LOCAL_LDLIBS += $(hostLdLibs) LOCAL_LDLIBS_darwin := $(hostLdLibs_darwin)
LOCAL_CFLAGS += $(cFlags) LOCAL_LDLIBS_linux := $(hostLdLibs_linux)
LOCAL_CPPFLAGS += $(cppFlags)
LOCAL_C_INCLUDES += $(protoIncludes)
include $(BUILD_HOST_EXECUTABLE) include $(BUILD_HOST_EXECUTABLE)
ifeq ($(ONE_SHOT_MAKEFILE),) ifeq ($(ONE_SHOT_MAKEFILE),)

View File

@@ -20,8 +20,6 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <string> #include <string>
using namespace android;
namespace aapt { namespace aapt {
TEST(StringPoolTest, InsertOneString) { TEST(StringPoolTest, InsertOneString) {
@@ -171,24 +169,28 @@ TEST(StringPoolTest, DoNotDedupeStyleWithSameStringAsNonStyle) {
} }
TEST(StringPoolTest, FlattenEmptyStringPoolUtf8) { TEST(StringPoolTest, FlattenEmptyStringPoolUtf8) {
using namespace android; // For NO_ERROR on Windows.
StringPool pool; StringPool pool;
BigBuffer buffer(1024); BigBuffer buffer(1024);
StringPool::flattenUtf8(&buffer, pool); StringPool::flattenUtf8(&buffer, pool);
std::unique_ptr<uint8_t[]> data = util::copy(buffer); std::unique_ptr<uint8_t[]> data = util::copy(buffer);
android::ResStringPool test; ResStringPool test;
ASSERT_EQ(test.setTo(data.get(), buffer.size()), android::NO_ERROR); ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
} }
TEST(StringPoolTest, FlattenOddCharactersUtf16) { TEST(StringPoolTest, FlattenOddCharactersUtf16) {
using namespace android; // For NO_ERROR on Windows.
StringPool pool; StringPool pool;
pool.makeRef(u"\u093f"); pool.makeRef(u"\u093f");
BigBuffer buffer(1024); BigBuffer buffer(1024);
StringPool::flattenUtf16(&buffer, pool); StringPool::flattenUtf16(&buffer, pool);
std::unique_ptr<uint8_t[]> data = util::copy(buffer); std::unique_ptr<uint8_t[]> data = util::copy(buffer);
android::ResStringPool test; ResStringPool test;
ASSERT_EQ(test.setTo(data.get(), buffer.size()), android::NO_ERROR); ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
size_t len = 0; size_t len = 0;
const char16_t* str = test.stringAt(0, &len); const char16_t* str = test.stringAt(0, &len);
EXPECT_EQ(1u, len); EXPECT_EQ(1u, len);
@@ -199,6 +201,8 @@ TEST(StringPoolTest, FlattenOddCharactersUtf16) {
constexpr const char16_t* sLongString = u"バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンスを抑え、バイブレーション、位置情報サービス、大半のバックグラウンドデータを制限します。メール、SMSや、同期を使 用するその他のアプリは、起動しても更新されないことがあります。バッテリーセーバーは端末の充電中は自動的にOFFになります。"; constexpr const char16_t* sLongString = u"バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンスを抑え、バイブレーション、位置情報サービス、大半のバックグラウンドデータを制限します。メール、SMSや、同期を使 用するその他のアプリは、起動しても更新されないことがあります。バッテリーセーバーは端末の充電中は自動的にOFFになります。";
TEST(StringPoolTest, FlattenUtf8) { TEST(StringPoolTest, FlattenUtf8) {
using namespace android; // For NO_ERROR on Windows.
StringPool pool; StringPool pool;
StringPool::Ref ref1 = pool.makeRef(u"hello"); StringPool::Ref ref1 = pool.makeRef(u"hello");
@@ -219,8 +223,8 @@ TEST(StringPoolTest, FlattenUtf8) {
std::unique_ptr<uint8_t[]> data = util::copy(buffer); std::unique_ptr<uint8_t[]> data = util::copy(buffer);
{ {
android::ResStringPool test; ResStringPool test;
ASSERT_EQ(test.setTo(data.get(), buffer.size()), android::NO_ERROR); ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
EXPECT_EQ(util::getString(test, 0), u"hello"); EXPECT_EQ(util::getString(test, 0), u"hello");
EXPECT_EQ(util::getString(test, 1), u"goodbye"); EXPECT_EQ(util::getString(test, 1), u"goodbye");

View File

@@ -20,6 +20,8 @@
#include "compile/PseudolocaleGenerator.h" #include "compile/PseudolocaleGenerator.h"
#include "compile/Pseudolocalizer.h" #include "compile/Pseudolocalizer.h"
#include <algorithm>
namespace aapt { namespace aapt {
std::unique_ptr<StyledString> pseudolocalizeStyledString(StyledString* string, std::unique_ptr<StyledString> pseudolocalizeStyledString(StyledString* string,

View File

@@ -24,6 +24,7 @@
#include "util/BigBuffer.h" #include "util/BigBuffer.h"
#include <android-base/macros.h> #include <android-base/macros.h>
#include <algorithm>
#include <type_traits> #include <type_traits>
#include <numeric> #include <numeric>

View File

@@ -21,6 +21,7 @@
#include "xml/XmlDom.h" #include "xml/XmlDom.h"
#include <androidfw/ResourceTypes.h> #include <androidfw/ResourceTypes.h>
#include <algorithm>
#include <utils/misc.h> #include <utils/misc.h>
#include <vector> #include <vector>

View File

@@ -46,6 +46,8 @@ public:
::testing::AssertionResult flatten(xml::XmlResource* doc, android::ResXMLTree* outTree, ::testing::AssertionResult flatten(xml::XmlResource* doc, android::ResXMLTree* outTree,
XmlFlattenerOptions options = {}) { XmlFlattenerOptions options = {}) {
using namespace android; // For NO_ERROR on windows because it is a macro.
BigBuffer buffer(1024); BigBuffer buffer(1024);
XmlFlattener flattener(&buffer, options); XmlFlattener flattener(&buffer, options);
if (!flattener.consume(mContext.get(), doc)) { if (!flattener.consume(mContext.get(), doc)) {
@@ -53,7 +55,7 @@ public:
} }
std::unique_ptr<uint8_t[]> data = util::copy(buffer); std::unique_ptr<uint8_t[]> data = util::copy(buffer);
if (outTree->setTo(data.get(), buffer.size(), true) != android::NO_ERROR) { if (outTree->setTo(data.get(), buffer.size(), true) != NO_ERROR) {
return ::testing::AssertionFailure() << "flattened XML is corrupt"; return ::testing::AssertionFailure() << "flattened XML is corrupt";
} }
return ::testing::AssertionSuccess(); return ::testing::AssertionSuccess();

View File

@@ -49,16 +49,18 @@ struct AnnotationProcessorTest : public ::testing::Test {
}; };
TEST_F(AnnotationProcessorTest, EmitsDeprecated) { TEST_F(AnnotationProcessorTest, EmitsDeprecated) {
ASSERT_TRUE(parse(R"EOF( const char* xmlInput = R"EOF(
<resources> <resources>
<declare-styleable name="foo"> <declare-styleable name="foo">
<!-- Some comment, and it should contain <!-- Some comment, and it should contain
a marker word, something that marks a marker word, something that marks
this resource as nor needed. this resource as nor needed.
{@deprecated That's the marker! } --> {@deprecated That's the marker! } -->
<attr name="autoText" format="boolean" /> <attr name="autoText" format="boolean" />
</declare-styleable> </declare-styleable>
</resources>)EOF")); </resources>)EOF";
ASSERT_TRUE(parse(xmlInput));
Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/autoText"); Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/autoText");
ASSERT_NE(nullptr, attr); ASSERT_NE(nullptr, attr);

View File

@@ -318,7 +318,7 @@ void JavaClassGenerator::addMembersToStyleableClass(const StringPiece16& package
} }
std::unique_ptr<IntMember> indexMember = util::make_unique<IntMember>( std::unique_ptr<IntMember> indexMember = util::make_unique<IntMember>(
sortedAttributes[i].fieldName, i); sortedAttributes[i].fieldName, static_cast<uint32_t>(i));
AnnotationProcessor* attrProcessor = indexMember->getCommentBuilder(); AnnotationProcessor* attrProcessor = indexMember->getCommentBuilder();

View File

@@ -239,13 +239,15 @@ TEST(JavaClassGeneratorTest, CommentsForSimpleResourcesArePresent) {
ASSERT_TRUE(generator.generate(u"android", &out)); ASSERT_TRUE(generator.generate(u"android", &out));
std::string actual = out.str(); std::string actual = out.str();
EXPECT_NE(std::string::npos, actual.find( const char* expectedText =
R"EOF(/** R"EOF(/**
* This is a comment * This is a comment
* @deprecated * @deprecated
*/ */
@Deprecated @Deprecated
public static final int foo=0x01010000;)EOF")); public static final int foo=0x01010000;)EOF";
EXPECT_NE(std::string::npos, actual.find(expectedText));
} }
TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) { TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) {

View File

@@ -104,28 +104,34 @@ TEST(ManifestClassGeneratorTest, CommentsAndAnnotationsArePresent) {
std::string actual; std::string actual;
ASSERT_TRUE(getManifestClassText(context.get(), manifest.get(), &actual)); ASSERT_TRUE(getManifestClassText(context.get(), manifest.get(), &actual));
EXPECT_NE(std::string::npos, actual.find( const char* expectedAccessInternet =
R"EOF( /** R"EOF( /**
* Required to access the internet. * Required to access the internet.
* Added in API 1. * Added in API 1.
*/ */
public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)EOF")); public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)EOF";
EXPECT_NE(std::string::npos, actual.find( EXPECT_NE(std::string::npos, actual.find(expectedAccessInternet));
const char* expectedPlayOutside =
R"EOF( /** R"EOF( /**
* @deprecated This permission is for playing outside. * @deprecated This permission is for playing outside.
*/ */
@Deprecated @Deprecated
public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)EOF")); public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)EOF";
EXPECT_NE(std::string::npos, actual.find( EXPECT_NE(std::string::npos, actual.find(expectedPlayOutside));
const char* expectedSecret =
R"EOF( /** R"EOF( /**
* This is a private permission for system only! * This is a private permission for system only!
* @hide * @hide
* @SystemApi * @SystemApi
*/ */
@android.annotation.SystemApi @android.annotation.SystemApi
public static final String SECRET="android.permission.SECRET";)EOF")); public static final String SECRET="android.permission.SECRET";)EOF";
EXPECT_NE(std::string::npos, actual.find(expectedSecret));
} }
} // namespace aapt } // namespace aapt

View File

@@ -388,6 +388,10 @@ private:
std::unique_ptr<ResourceTable> deserializeTableFromPb(const pb::ResourceTable& pbTable, std::unique_ptr<ResourceTable> deserializeTableFromPb(const pb::ResourceTable& pbTable,
const Source& source, const Source& source,
IDiagnostics* diag) { IDiagnostics* diag) {
// We import the android namespace because on Windows NO_ERROR is a macro, not an enum, which
// causes errors when qualifying it with android::
using namespace android;
std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>(); std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
if (!pbTable.has_string_pool()) { if (!pbTable.has_string_pool()) {
@@ -395,29 +399,29 @@ std::unique_ptr<ResourceTable> deserializeTableFromPb(const pb::ResourceTable& p
return {}; return {};
} }
android::ResStringPool valuePool; ResStringPool valuePool;
android::status_t result = valuePool.setTo(pbTable.string_pool().data().data(), status_t result = valuePool.setTo(pbTable.string_pool().data().data(),
pbTable.string_pool().data().size()); pbTable.string_pool().data().size());
if (result != android::NO_ERROR) { if (result != NO_ERROR) {
diag->error(DiagMessage(source) << "invalid string pool"); diag->error(DiagMessage(source) << "invalid string pool");
return {}; return {};
} }
android::ResStringPool sourcePool; ResStringPool sourcePool;
if (pbTable.has_source_pool()) { if (pbTable.has_source_pool()) {
result = sourcePool.setTo(pbTable.source_pool().data().data(), result = sourcePool.setTo(pbTable.source_pool().data().data(),
pbTable.source_pool().data().size()); pbTable.source_pool().data().size());
if (result != android::NO_ERROR) { if (result != NO_ERROR) {
diag->error(DiagMessage(source) << "invalid source pool"); diag->error(DiagMessage(source) << "invalid source pool");
return {}; return {};
} }
} }
android::ResStringPool symbolPool; ResStringPool symbolPool;
if (pbTable.has_symbol_pool()) { if (pbTable.has_symbol_pool()) {
result = symbolPool.setTo(pbTable.symbol_pool().data().data(), result = symbolPool.setTo(pbTable.symbol_pool().data().data(),
pbTable.symbol_pool().data().size()); pbTable.symbol_pool().data().size());
if (result != android::NO_ERROR) { if (result != NO_ERROR) {
diag->error(DiagMessage(source) << "invalid symbol pool"); diag->error(DiagMessage(source) << "invalid symbol pool");
return {}; return {};
} }

View File

@@ -18,6 +18,7 @@
#include "ResourceTable.h" #include "ResourceTable.h"
#include "split/TableSplitter.h" #include "split/TableSplitter.h"
#include <algorithm>
#include <map> #include <map>
#include <set> #include <set>
#include <unordered_map> #include <unordered_map>

View File

@@ -26,7 +26,7 @@
#include <androidfw/ResourceTypes.h> #include <androidfw/ResourceTypes.h>
#include <androidfw/TypeWrappers.h> #include <androidfw/TypeWrappers.h>
#include <android-base/macros.h> #include <android-base/macros.h>
#include <algorithm>
#include <map> #include <map>
#include <string> #include <string>

View File

@@ -17,6 +17,7 @@
#include "util/Files.h" #include "util/Files.h"
#include "util/Util.h" #include "util/Util.h"
#include <algorithm>
#include <cerrno> #include <cerrno>
#include <cstdio> #include <cstdio>
#include <dirent.h> #include <dirent.h>

View File

@@ -17,6 +17,8 @@
#ifndef AAPT_MAYBE_H #ifndef AAPT_MAYBE_H
#define AAPT_MAYBE_H #define AAPT_MAYBE_H
#include "util/TypeTraits.h"
#include <cassert> #include <cassert>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
@@ -276,13 +278,15 @@ inline Maybe<T> make_nothing() {
} }
/** /**
* Define the == operator between Maybe<T> and Maybe<U> if the operator T == U is defined. * Define the == operator between Maybe<T> and Maybe<U> only if the operator T == U is defined.
* Otherwise this won't be defined and the compiler will yell at the callsite instead of inside * That way the compiler will show an error at the callsite when comparing two Maybe<> objects
* Maybe.h. * whose inner types can't be compared.
*/ */
template <typename T, typename U> template <typename T, typename U>
auto operator==(const Maybe<T>& a, const Maybe<U>& b) typename std::enable_if<
-> decltype(std::declval<T> == std::declval<U>) { has_eq_op<T, U>::value,
bool
>::type operator==(const Maybe<T>& a, const Maybe<U>& b) {
if (a && b) { if (a && b) {
return a.value() == b.value(); return a.value() == b.value();
} else if (!a && !b) { } else if (!a && !b) {
@@ -295,8 +299,10 @@ auto operator==(const Maybe<T>& a, const Maybe<U>& b)
* Same as operator== but negated. * Same as operator== but negated.
*/ */
template <typename T, typename U> template <typename T, typename U>
auto operator!=(const Maybe<T>& a, const Maybe<U>& b) typename std::enable_if<
-> decltype(std::declval<T> == std::declval<U>) { has_eq_op<T, U>::value,
bool
>::type operator!=(const Maybe<T>& a, const Maybe<U>& b) {
return !(a == b); return !(a == b);
} }

View File

@@ -228,20 +228,24 @@ static void copyAttributes(Element* el, android::ResXMLParser* parser) {
std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnostics* diag, std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnostics* diag,
const Source& source) { const Source& source) {
// We import the android namespace because on Windows NO_ERROR is a macro, not an enum, which
// causes errors when qualifying it with android::
using namespace android;
std::unique_ptr<Node> root; std::unique_ptr<Node> root;
std::stack<Node*> nodeStack; std::stack<Node*> nodeStack;
android::ResXMLTree tree; ResXMLTree tree;
if (tree.setTo(data, dataLen) != android::NO_ERROR) { if (tree.setTo(data, dataLen) != NO_ERROR) {
return {}; return {};
} }
android::ResXMLParser::event_code_t code; ResXMLParser::event_code_t code;
while ((code = tree.next()) != android::ResXMLParser::BAD_DOCUMENT && while ((code = tree.next()) != ResXMLParser::BAD_DOCUMENT &&
code != android::ResXMLParser::END_DOCUMENT) { code != ResXMLParser::END_DOCUMENT) {
std::unique_ptr<Node> newNode; std::unique_ptr<Node> newNode;
switch (code) { switch (code) {
case android::ResXMLParser::START_NAMESPACE: { case ResXMLParser::START_NAMESPACE: {
std::unique_ptr<Namespace> node = util::make_unique<Namespace>(); std::unique_ptr<Namespace> node = util::make_unique<Namespace>();
size_t len; size_t len;
const char16_t* str16 = tree.getNamespacePrefix(&len); const char16_t* str16 = tree.getNamespacePrefix(&len);
@@ -257,7 +261,7 @@ std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnost
break; break;
} }
case android::ResXMLParser::START_TAG: { case ResXMLParser::START_TAG: {
std::unique_ptr<Element> node = util::make_unique<Element>(); std::unique_ptr<Element> node = util::make_unique<Element>();
size_t len; size_t len;
const char16_t* str16 = tree.getElementNamespace(&len); const char16_t* str16 = tree.getElementNamespace(&len);
@@ -276,7 +280,7 @@ std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnost
break; break;
} }
case android::ResXMLParser::TEXT: { case ResXMLParser::TEXT: {
std::unique_ptr<Text> node = util::make_unique<Text>(); std::unique_ptr<Text> node = util::make_unique<Text>();
size_t len; size_t len;
const char16_t* str16 = tree.getText(&len); const char16_t* str16 = tree.getText(&len);
@@ -287,8 +291,8 @@ std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnost
break; break;
} }
case android::ResXMLParser::END_NAMESPACE: case ResXMLParser::END_NAMESPACE:
case android::ResXMLParser::END_TAG: case ResXMLParser::END_TAG:
assert(!nodeStack.empty()); assert(!nodeStack.empty());
nodeStack.pop(); nodeStack.pop();
break; break;

View File

@@ -33,22 +33,22 @@ TEST(XmlUtilTest, ExtractPackageFromNamespace) {
xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/res/a"); xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/res/a");
AAPT_ASSERT_TRUE(p); AAPT_ASSERT_TRUE(p);
EXPECT_EQ(std::u16string(u"a"), p.value().package); EXPECT_EQ(std::u16string(u"a"), p.value().package);
EXPECT_EQ(false, p.value().privateNamespace); EXPECT_FALSE(p.value().privateNamespace);
p = xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/prv/res/android"); p = xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/prv/res/android");
AAPT_ASSERT_TRUE(p); AAPT_ASSERT_TRUE(p);
EXPECT_EQ(std::u16string(u"android"), p.value().package); EXPECT_EQ(std::u16string(u"android"), p.value().package);
EXPECT_EQ(true, p.value().privateNamespace); EXPECT_TRUE(p.value().privateNamespace);
p = xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/prv/res/com.test"); p = xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/prv/res/com.test");
AAPT_ASSERT_TRUE(p); AAPT_ASSERT_TRUE(p);
EXPECT_EQ(std::u16string(u"com.test"), p.value().package); EXPECT_EQ(std::u16string(u"com.test"), p.value().package);
EXPECT_EQ(true, p.value().privateNamespace); EXPECT_TRUE(p.value().privateNamespace);
p = xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/res-auto"); p = xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/res-auto");
AAPT_ASSERT_TRUE(p); AAPT_ASSERT_TRUE(p);
EXPECT_EQ(std::u16string(), p.value().package); EXPECT_EQ(std::u16string(), p.value().package);
EXPECT_EQ(true, p.value().privateNamespace); EXPECT_TRUE(p.value().privateNamespace);
} }
} // namespace aapt } // namespace aapt