#include "XMLNode.h"
#include "ResourceFilter.h"
+#include "ResourceIdCache.h"
+#include <androidfw/ResourceTypes.h>
#include <utils/ByteOrder.h>
-#include <utils/ResourceTypes.h>
#include <stdarg.h>
#define NOISY(x) //x
const String16 public16("public");
const String16 public_padding16("public-padding");
const String16 private_symbols16("private-symbols");
+ const String16 java_symbol16("java-symbol");
const String16 add_resource16("add-resource");
const String16 skip16("skip");
const String16 eat_comment16("eat-comment");
}
continue;
+ } else if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) {
+ SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
+
+ String16 type;
+ ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
+ if (typeIdx < 0) {
+ srcPos.error("A 'type' attribute is required for <public>\n");
+ hasErrors = localHasErrors = true;
+ }
+ type = String16(block.getAttributeStringValue(typeIdx, &len));
+
+ String16 name;
+ ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
+ if (nameIdx < 0) {
+ srcPos.error("A 'name' attribute is required for <public>\n");
+ hasErrors = localHasErrors = true;
+ }
+ name = String16(block.getAttributeStringValue(nameIdx, &len));
+
+ sp<AaptSymbols> symbols = assets->getJavaSymbolsFor(String8("R"));
+ if (symbols != NULL) {
+ symbols = symbols->addNestedSymbol(String8(type), srcPos);
+ }
+ if (symbols != NULL) {
+ symbols->makeSymbolJavaSymbol(String8(name), srcPos);
+ String16 comment(
+ block.getComment(&len) ? block.getComment(&len) : nulStr);
+ symbols->appendComment(String8(name), comment, srcPos);
+ } else {
+ srcPos.error("Unable to create symbols!\n");
+ hasErrors = localHasErrors = true;
+ }
+
+ while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
+ if (code == ResXMLTree::END_TAG) {
+ if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) {
+ break;
+ }
+ }
+ }
+ continue;
+
+
} else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
const String16& name,
bool onlyPublic) const
{
+ uint32_t id = ResourceIdCache::lookup(package, type, name, onlyPublic);
+ if (id != 0) return id; // cache hit
+
sp<Package> p = mPackages.valueFor(package);
if (p == NULL) return 0;
}
if (Res_INTERNALID(rid)) {
- return rid;
+ return ResourceIdCache::store(package, type, name, onlyPublic, rid);
}
- return Res_MAKEID(p->getAssignedId()-1,
- Res_GETTYPE(rid),
- Res_GETENTRY(rid));
+ return ResourceIdCache::store(package, type, name, onlyPublic,
+ Res_MAKEID(p->getAssignedId()-1, Res_GETTYPE(rid), Res_GETENTRY(rid)));
}
sp<Type> t = p->getTypes().valueFor(type);
if (c == NULL) return 0;
int32_t ei = c->getEntryIndex();
if (ei < 0) return 0;
- return getResId(p, t, ei);
+
+ return ResourceIdCache::store(package, type, name, onlyPublic,
+ getResId(p, t, ei));
}
uint32_t ResourceTable::getResId(const String16& ref,
const char16_t* end = name + nameLen;
const char16_t* pos = name;
- bool failed = false;
- while (pos < end && !failed) {
+ while (pos < end) {
const char16_t* start = pos;
- end++;
while (pos < end && *pos != '|') {
pos++;
}
// Didn't find this flag identifier.
return false;
}
- if (pos < end) {
- pos++;
- }
+ pos++;
}
return true;
// Iterate through all data, collecting all values (strings,
// references, etc).
- StringPool valueStrings = StringPool(false, useUTF8);
+ StringPool valueStrings(useUTF8);
Vector<sp<Entry> > allEntries;
for (pi=0; pi<N; pi++) {
sp<Package> p = mOrderedPackages.itemAt(pi);
continue;
}
- StringPool typeStrings = StringPool(false, useUTF8);
- StringPool keyStrings = StringPool(false, useUTF8);
+ StringPool typeStrings(useUTF8);
+ StringPool keyStrings(useUTF8);
const size_t N = p->getOrderedTypes().size();
for (size_t ti=0; ti<N; ti++) {
const bool filterable = (typeName != mipmap16);
const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0;
+
+ // Until a non-NO_ENTRY value has been written for a resource,
+ // that resource is invalid; validResources[i] represents
+ // the item at t->getOrderedConfigs().itemAt(i).
+ Vector<bool> validResources;
+ validResources.insertAt(false, 0, N);
// First write the typeSpec chunk, containing information about
// each resource entry in this type.
NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
"orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
- "sw%ddp w%ddp h%ddp\n",
+ "sw%ddp w%ddp h%ddp dir:%d\n",
ti+1,
config.mcc, config.mnc,
config.language[0] ? config.language[0] : '-',
config.screenHeight,
config.smallestScreenWidthDp,
config.screenWidthDp,
- config.screenHeightDp));
+ config.screenHeightDp,
+ config.layoutDirection));
if (filterable && !filter.match(config)) {
continue;
tHeader->config = config;
NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
"orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
- "sw%ddp w%ddp h%ddp\n",
+ "sw%ddp w%ddp h%ddp dir:%d\n",
ti+1,
tHeader->config.mcc, tHeader->config.mnc,
tHeader->config.language[0] ? tHeader->config.language[0] : '-',
tHeader->config.screenHeight,
tHeader->config.smallestScreenWidthDp,
tHeader->config.screenWidthDp,
- tHeader->config.screenHeightDp));
+ tHeader->config.screenHeightDp,
+ tHeader->config.layoutDirection));
tHeader->config.swapHtoD();
// Build the entries inside of this type.
if (amt < 0) {
return amt;
}
+ validResources.editItemAt(ei) = true;
} else {
index[ei] = htodl(ResTable_type::NO_ENTRY);
}
(((uint8_t*)data->editData()) + typeStart);
tHeader->header.size = htodl(data->getSize()-typeStart);
}
+
+ for (size_t i = 0; i < N; ++i) {
+ if (!validResources[i]) {
+ sp<ConfigList> c = t->getOrderedConfigs().itemAt(i);
+ fprintf(stderr, "warning: no entries written for %s/%s\n",
+ String8(typeName).string(), String8(c->getName()).string());
+ }
+ }
}
// Fill in the rest of the package information.
if (config != NULL) {
NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c "
"orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
- "sw%ddp w%ddp h%ddp\n",
+ "sw%ddp w%ddp h%ddp dir:%d\n",
sourcePos.file.string(), sourcePos.line,
config->mcc, config->mnc,
config->language[0] ? config->language[0] : '-',
config->screenHeight,
config->smallestScreenWidthDp,
config->screenWidthDp,
- config->screenHeightDp));
+ config->screenHeightDp,
+ config->layoutDirection));
} else {
NOISY(printf("New entry at %s:%d: NULL config\n",
sourcePos.file.string(), sourcePos.line));
{
sp<Package> p = mPackages.valueFor(package);
if (p == NULL) {
- if (mBundle->getIsOverlayPackage()) {
- p = new Package(package, 0x00);
- } else if (mIsAppPackage) {
+ if (mIsAppPackage) {
if (mHaveAppPackage) {
fprintf(stderr, "Adding multiple application package resources; only one is allowed.\n"
"Use -x to create extended resources.\n");