Fix windows build of AAPT2
Change-Id: Ib8e1a4322510b582e9600a08d3118842c9abc73c
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#ifndef AAPT_BIG_BUFFER_H
|
||||
#define AAPT_BIG_BUFFER_H
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@@ -157,8 +157,12 @@ bool BinaryResourceParser::getSymbol(const void* data, ResourceNameRef* outSymbo
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reinterpret_cast<uintptr_t>(data) < reinterpret_cast<uintptr_t>(mData)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We only support 32 bit offsets right now.
|
||||
const ptrdiff_t offset = reinterpret_cast<uintptr_t>(data) -
|
||||
const uintptr_t offset = reinterpret_cast<uintptr_t>(data) -
|
||||
reinterpret_cast<uintptr_t>(mData);
|
||||
if (offset > std::numeric_limits<uint32_t>::max()) {
|
||||
return false;
|
||||
@@ -227,7 +231,7 @@ bool BinaryResourceParser::parseSymbolTable(const ResChunk_header* chunk) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mSymbolPool.setTo(parser.getChunk(), parser.getChunk()->size) != android::NO_ERROR) {
|
||||
if (mSymbolPool.setTo(parser.getChunk(), parser.getChunk()->size) != NO_ERROR) {
|
||||
Logger::error(mSource)
|
||||
<< "failed to parse symbol string pool with code: "
|
||||
<< mSymbolPool.getError()
|
||||
@@ -252,9 +256,9 @@ bool BinaryResourceParser::parseTable(const ResChunk_header* chunk) {
|
||||
while (ResChunkPullParser::isGoodEvent(parser.next())) {
|
||||
switch (parser.getChunk()->type) {
|
||||
case android::RES_STRING_POOL_TYPE:
|
||||
if (mValuePool.getError() == android::NO_INIT) {
|
||||
if (mValuePool.getError() == NO_INIT) {
|
||||
if (mValuePool.setTo(parser.getChunk(), parser.getChunk()->size) !=
|
||||
android::NO_ERROR) {
|
||||
NO_ERROR) {
|
||||
Logger::error(mSource)
|
||||
<< "failed to parse value string pool with code: "
|
||||
<< mValuePool.getError()
|
||||
@@ -281,7 +285,7 @@ bool BinaryResourceParser::parseTable(const ResChunk_header* chunk) {
|
||||
|
||||
case RES_TABLE_SOURCE_POOL_TYPE: {
|
||||
if (mSourcePool.setTo(getChunkData(*parser.getChunk()),
|
||||
getChunkDataLen(*parser.getChunk())) != android::NO_ERROR) {
|
||||
getChunkDataLen(*parser.getChunk())) != NO_ERROR) {
|
||||
Logger::error(mSource)
|
||||
<< "failed to parse source pool with code: "
|
||||
<< mSourcePool.getError()
|
||||
@@ -319,7 +323,7 @@ bool BinaryResourceParser::parseTable(const ResChunk_header* chunk) {
|
||||
}
|
||||
|
||||
bool BinaryResourceParser::parsePackage(const ResChunk_header* chunk) {
|
||||
if (mValuePool.getError() != android::NO_ERROR) {
|
||||
if (mValuePool.getError() != NO_ERROR) {
|
||||
Logger::error(mSource)
|
||||
<< "no value string pool for ResTable."
|
||||
<< std::endl;
|
||||
@@ -356,9 +360,9 @@ bool BinaryResourceParser::parsePackage(const ResChunk_header* chunk) {
|
||||
while (ResChunkPullParser::isGoodEvent(parser.next())) {
|
||||
switch (parser.getChunk()->type) {
|
||||
case android::RES_STRING_POOL_TYPE:
|
||||
if (mTypePool.getError() == android::NO_INIT) {
|
||||
if (mTypePool.getError() == NO_INIT) {
|
||||
if (mTypePool.setTo(parser.getChunk(), parser.getChunk()->size) !=
|
||||
android::NO_ERROR) {
|
||||
NO_ERROR) {
|
||||
Logger::error(mSource)
|
||||
<< "failed to parse type string pool with code "
|
||||
<< mTypePool.getError()
|
||||
@@ -366,9 +370,9 @@ bool BinaryResourceParser::parsePackage(const ResChunk_header* chunk) {
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
} else if (mKeyPool.getError() == android::NO_INIT) {
|
||||
} else if (mKeyPool.getError() == NO_INIT) {
|
||||
if (mKeyPool.setTo(parser.getChunk(), parser.getChunk()->size) !=
|
||||
android::NO_ERROR) {
|
||||
NO_ERROR) {
|
||||
Logger::error(mSource)
|
||||
<< "failed to parse key string pool with code "
|
||||
<< mKeyPool.getError()
|
||||
@@ -429,7 +433,7 @@ bool BinaryResourceParser::parsePackage(const ResChunk_header* chunk) {
|
||||
}
|
||||
|
||||
bool BinaryResourceParser::parseTypeSpec(const ResChunk_header* chunk) {
|
||||
if (mTypePool.getError() != android::NO_ERROR) {
|
||||
if (mTypePool.getError() != NO_ERROR) {
|
||||
Logger::error(mSource)
|
||||
<< "no type string pool available for ResTable_typeSpec."
|
||||
<< std::endl;
|
||||
@@ -456,14 +460,14 @@ bool BinaryResourceParser::parseTypeSpec(const ResChunk_header* chunk) {
|
||||
}
|
||||
|
||||
bool BinaryResourceParser::parseType(const ResChunk_header* chunk) {
|
||||
if (mTypePool.getError() != android::NO_ERROR) {
|
||||
if (mTypePool.getError() != NO_ERROR) {
|
||||
Logger::error(mSource)
|
||||
<< "no type string pool available for ResTable_typeSpec."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mKeyPool.getError() != android::NO_ERROR) {
|
||||
if (mKeyPool.getError() != NO_ERROR) {
|
||||
Logger::error(mSource)
|
||||
<< "no key string pool available for ResTable_type."
|
||||
<< std::endl;
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_MS_C_RUNTIME
|
||||
// Windows includes.
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
namespace aapt {
|
||||
|
||||
FileType getFileType(const StringPiece& path) {
|
||||
@@ -43,10 +48,14 @@ FileType getFileType(const StringPiece& path) {
|
||||
return FileType::kBlockDev;
|
||||
} else if (S_ISFIFO(sb.st_mode)) {
|
||||
return FileType::kFifo;
|
||||
#if defined(S_ISLNK)
|
||||
} else if (S_ISLNK(sb.st_mode)) {
|
||||
return FileType::kSymlink;
|
||||
#endif
|
||||
#if defined(S_ISSOCK)
|
||||
} else if (S_ISSOCK(sb.st_mode)) {
|
||||
return FileType::kSocket;
|
||||
#endif
|
||||
} else {
|
||||
return FileType::kUnknown;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "Source.h"
|
||||
#include "StringPiece.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "ResourceValues.h"
|
||||
#include "StringPiece.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
@@ -87,10 +88,11 @@ bool JavaClassGenerator::generateType(std::ostream& out, const ResourceTableType
|
||||
assert(id.isValid());
|
||||
|
||||
if (!isValidSymbol(entry->name)) {
|
||||
mError = (std::stringstream()
|
||||
<< "invalid symbol name '"
|
||||
<< StringPiece16(entry->name)
|
||||
<< "'").str();
|
||||
std::stringstream err;
|
||||
err << "invalid symbol name '"
|
||||
<< StringPiece16(entry->name)
|
||||
<< "'";
|
||||
mError = err.str();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -164,10 +166,11 @@ bool JavaClassGenerator::generate(std::ostream& out) {
|
||||
for (const auto& entry : type->entries) {
|
||||
assert(!entry->values.empty());
|
||||
if (!isValidSymbol(entry->name)) {
|
||||
mError = (std::stringstream()
|
||||
<< "invalid symbol name '"
|
||||
<< StringPiece16(entry->name)
|
||||
<< "'").str();
|
||||
std::stringstream err;
|
||||
err << "invalid symbol name '"
|
||||
<< StringPiece16(entry->name)
|
||||
<< "'";
|
||||
mError = err.str();
|
||||
return false;
|
||||
}
|
||||
entry->values.front().value->accept(*this, GenArgs{ out, *entry });
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <androidfw/AssetManager.h>
|
||||
#include <array>
|
||||
#include <bitset>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
|
||||
@@ -171,6 +171,9 @@ bool loadBinaryResourceTable(std::shared_ptr<ResourceTable> table, const Source&
|
||||
}
|
||||
|
||||
bool loadResTable(android::ResTable* table, const Source& source) {
|
||||
// For NO_ERROR (which on Windows is a MACRO).
|
||||
using namespace android;
|
||||
|
||||
std::ifstream ifs(source.path, std::ifstream::in | std::ifstream::binary);
|
||||
if (!ifs) {
|
||||
Logger::error(source) << strerror(errno) << std::endl;
|
||||
@@ -187,7 +190,7 @@ bool loadResTable(android::ResTable* table, const Source& source) {
|
||||
char* buf = new char[dataSize];
|
||||
ifs.read(buf, dataSize);
|
||||
|
||||
bool result = table->add(buf, dataSize, -1, true) == android::NO_ERROR;
|
||||
bool result = table->add(buf, dataSize, -1, true) == NO_ERROR;
|
||||
|
||||
delete [] buf;
|
||||
return result;
|
||||
@@ -426,6 +429,8 @@ struct AaptOptions {
|
||||
};
|
||||
|
||||
bool compileAndroidManifest(std::shared_ptr<Resolver> resolver, const AaptOptions& options) {
|
||||
using namespace android;
|
||||
|
||||
Source outSource = options.output;
|
||||
appendPath(&outSource.path, "AndroidManifest.xml");
|
||||
|
||||
@@ -456,8 +461,8 @@ bool compileAndroidManifest(std::shared_ptr<Resolver> resolver, const AaptOption
|
||||
p += b.size;
|
||||
}
|
||||
|
||||
android::ResXMLTree tree;
|
||||
if (tree.setTo(data.get(), outBuffer.size()) != android::NO_ERROR) {
|
||||
ResXMLTree tree;
|
||||
if (tree.setTo(data.get(), outBuffer.size()) != NO_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ bool ManifestValidator::validateAttributeImpl(const StringPiece16& element,
|
||||
<< "> attribute '"
|
||||
<< attributeName
|
||||
<< "' has invalid character '"
|
||||
<< *badIter
|
||||
<< StringPiece16(badIter, 1)
|
||||
<< "'."
|
||||
<< std::endl;
|
||||
return false;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "StringPiece.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
|
||||
@@ -973,7 +973,7 @@ std::unique_ptr<Attribute> ResourceParser::parseAttrImpl(XmlPullParser* parser,
|
||||
|
||||
std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(weak);
|
||||
attr->symbols.swap(items);
|
||||
attr->typeMask = typeMask ? typeMask : android::ResTable_map::TYPE_ANY;
|
||||
attr->typeMask = typeMask ? typeMask : uint32_t(android::ResTable_map::TYPE_ANY);
|
||||
return attr;
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ bool ResourceTable::addResource(const ResourceNameRef& name, const ResourceId re
|
||||
<< "' has invalid entry name '"
|
||||
<< name.entry
|
||||
<< "'. Invalid character '"
|
||||
<< *badCharIter
|
||||
<< StringPiece16(badCharIter, 1)
|
||||
<< "'."
|
||||
<< std::endl;
|
||||
return false;
|
||||
@@ -258,7 +258,7 @@ bool ResourceTable::markPublic(const ResourceNameRef& name, const ResourceId res
|
||||
<< "' has invalid entry name '"
|
||||
<< name.entry
|
||||
<< "'. Invalid character '"
|
||||
<< *badCharIter
|
||||
<< StringPiece16(badCharIter, 1)
|
||||
<< "'."
|
||||
<< std::endl;
|
||||
return false;
|
||||
@@ -314,21 +314,21 @@ bool ResourceTable::markPublic(const ResourceNameRef& name, const ResourceId res
|
||||
std::tuple<const ResourceTableType*, const ResourceEntry*>
|
||||
ResourceTable::findResource(const ResourceNameRef& name) const {
|
||||
if (name.package != mPackage) {
|
||||
return {nullptr, nullptr};
|
||||
return {};
|
||||
}
|
||||
|
||||
auto iter = std::lower_bound(mTypes.begin(), mTypes.end(), name.type, lessThanType);
|
||||
if (iter == mTypes.end() || (*iter)->type != name.type) {
|
||||
return {nullptr, nullptr};
|
||||
return {};
|
||||
}
|
||||
|
||||
const std::unique_ptr<ResourceTableType>& type = *iter;
|
||||
auto iter2 = std::lower_bound(type->entries.begin(), type->entries.end(), name.entry,
|
||||
lessThanEntry);
|
||||
if (iter2 == type->entries.end() || name.entry != (*iter2)->name) {
|
||||
return {nullptr, nullptr};
|
||||
return {};
|
||||
}
|
||||
return {iter->get(), iter2->get()};
|
||||
return std::make_tuple(iter->get(), iter2->get());
|
||||
}
|
||||
|
||||
} // namespace aapt
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <string>
|
||||
|
||||
using namespace android;
|
||||
|
||||
namespace aapt {
|
||||
|
||||
TEST(StringPoolTest, InsertOneString) {
|
||||
@@ -189,28 +191,28 @@ TEST(StringPoolTest, FlattenUtf8) {
|
||||
}
|
||||
|
||||
{
|
||||
android::ResStringPool test;
|
||||
ASSERT_EQ(android::NO_ERROR, test.setTo(data, buffer.size()));
|
||||
ResStringPool test;
|
||||
ASSERT_TRUE(test.setTo(data, buffer.size()) == NO_ERROR);
|
||||
|
||||
EXPECT_EQ(util::getString(test, 0), u"hello");
|
||||
EXPECT_EQ(util::getString(test, 1), u"goodbye");
|
||||
EXPECT_EQ(util::getString(test, 2), sLongString);
|
||||
EXPECT_EQ(util::getString(test, 3), u"style");
|
||||
|
||||
const android::ResStringPool_span* span = test.styleAt(3);
|
||||
const ResStringPool_span* span = test.styleAt(3);
|
||||
ASSERT_NE(nullptr, span);
|
||||
EXPECT_EQ(util::getString(test, span->name.index), u"b");
|
||||
EXPECT_EQ(0u, span->firstChar);
|
||||
EXPECT_EQ(1u, span->lastChar);
|
||||
span++;
|
||||
|
||||
ASSERT_NE(android::ResStringPool_span::END, span->name.index);
|
||||
ASSERT_NE(ResStringPool_span::END, span->name.index);
|
||||
EXPECT_EQ(util::getString(test, span->name.index), u"i");
|
||||
EXPECT_EQ(2u, span->firstChar);
|
||||
EXPECT_EQ(3u, span->lastChar);
|
||||
span++;
|
||||
|
||||
EXPECT_EQ(android::ResStringPool_span::END, span->name.index);
|
||||
EXPECT_EQ(ResStringPool_span::END, span->name.index);
|
||||
}
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "TableFlattener.h"
|
||||
#include "Util.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <androidfw/ResourceTypes.h>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ template <typename Iterator>
|
||||
|
||||
inline ::std::function<::std::ostream&(::std::ostream&)> formatSize(size_t size) {
|
||||
return [size](::std::ostream& out) -> ::std::ostream& {
|
||||
constexpr size_t K = 1024;
|
||||
constexpr size_t K = 1024u;
|
||||
constexpr size_t M = K * K;
|
||||
constexpr size_t G = M * K;
|
||||
if (size < K) {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "XmlPullParser.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace aapt {
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
using namespace android;
|
||||
|
||||
namespace aapt {
|
||||
|
||||
constexpr const char* kXmlPreamble = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
|
||||
@@ -40,16 +42,16 @@ public:
|
||||
|
||||
table->addResource(ResourceName{ {}, ResourceType::kAttr, u"id" },
|
||||
ResourceId{ 0x01010000 }, {}, {},
|
||||
util::make_unique<Attribute>(false, android::ResTable_map::TYPE_ANY));
|
||||
util::make_unique<Attribute>(false, ResTable_map::TYPE_ANY));
|
||||
|
||||
table->addResource(ResourceName{ {}, ResourceType::kId, u"test" },
|
||||
ResourceId{ 0x01020000 }, {}, {}, util::make_unique<Id>());
|
||||
|
||||
mFlattener = std::make_shared<XmlFlattener>(
|
||||
std::make_shared<Resolver>(table, std::make_shared<android::AssetManager>()));
|
||||
std::make_shared<Resolver>(table, std::make_shared<AssetManager>()));
|
||||
}
|
||||
|
||||
::testing::AssertionResult testFlatten(std::istream& in, android::ResXMLTree* outTree) {
|
||||
::testing::AssertionResult testFlatten(std::istream& in, ResXMLTree* outTree) {
|
||||
std::stringstream input(kXmlPreamble);
|
||||
input << in.rdbuf() << std::endl;
|
||||
std::shared_ptr<XmlPullParser> xmlParser = std::make_shared<SourceXmlPullParser>(input);
|
||||
@@ -59,7 +61,7 @@ public:
|
||||
}
|
||||
|
||||
std::unique_ptr<uint8_t[]> data = util::copy(outBuffer);
|
||||
if (outTree->setTo(data.get(), outBuffer.size(), true) != android::NO_ERROR) {
|
||||
if (outTree->setTo(data.get(), outBuffer.size(), true) != NO_ERROR) {
|
||||
return ::testing::AssertionFailure();
|
||||
}
|
||||
return ::testing::AssertionSuccess();
|
||||
@@ -74,11 +76,11 @@ TEST_F(XmlFlattenerTest, ParseSimpleView) {
|
||||
<< " android:id=\"@id/test\">" << std::endl
|
||||
<< "</View>" << std::endl;
|
||||
|
||||
android::ResXMLTree tree;
|
||||
ResXMLTree tree;
|
||||
ASSERT_TRUE(testFlatten(input, &tree));
|
||||
|
||||
while (tree.next() != android::ResXMLTree::END_DOCUMENT) {
|
||||
ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
|
||||
while (tree.next() != ResXMLTree::END_DOCUMENT) {
|
||||
ASSERT_NE(tree.getEventType(), ResXMLTree::BAD_DOCUMENT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -116,20 +116,6 @@ public:
|
||||
const_iterator findAttribute(StringPiece16 namespaceUri, StringPiece16 name) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* Automatically reads up to the end tag of the element it was initialized with
|
||||
* when being destroyed.
|
||||
*/
|
||||
class AutoFinishElement {
|
||||
public:
|
||||
AutoFinishElement(const std::shared_ptr<XmlPullParser>& parser);
|
||||
~AutoFinishElement();
|
||||
|
||||
private:
|
||||
std::shared_ptr<XmlPullParser> mParser;
|
||||
int mDepth;
|
||||
};
|
||||
|
||||
//
|
||||
// Implementation
|
||||
//
|
||||
@@ -212,23 +198,6 @@ inline XmlPullParser::const_iterator XmlPullParser::findAttribute(StringPiece16
|
||||
return endIter;
|
||||
}
|
||||
|
||||
inline AutoFinishElement::AutoFinishElement(const std::shared_ptr<XmlPullParser>& parser) :
|
||||
mParser(parser), mDepth(parser->getDepth()) {
|
||||
}
|
||||
|
||||
inline AutoFinishElement::~AutoFinishElement() {
|
||||
int depth;
|
||||
XmlPullParser::Event event;
|
||||
while ((depth = mParser->getDepth()) >= mDepth &&
|
||||
XmlPullParser::isGoodEvent(event = mParser->getEvent())) {
|
||||
if (depth == mDepth && (event == XmlPullParser::Event::kEndElement ||
|
||||
event == XmlPullParser::Event::kEndNamespace)) {
|
||||
return;
|
||||
}
|
||||
mParser->next();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace aapt
|
||||
|
||||
#endif // AAPT_XML_PULL_PARSER_H
|
||||
|
||||
Reference in New Issue
Block a user