Merge "AAPT2: Enable windows build and make sure it builds" into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
f22df48067
@@ -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),)
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ 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
|
||||||
@@ -58,7 +58,9 @@ TEST_F(AnnotationProcessorTest, EmitsDeprecated) {
|
|||||||
{@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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user