use of org.robolectric.res.android.ResourceTypes.ResStringPool_header.Writer in project robolectric by robolectric.
the class AttributeSetBuilderImpl method build.
@Override
public AttributeSet build() {
Class<?> xmlBlockClass = ReflectionHelpers.loadClass(this.getClass().getClassLoader(), "android.content.res.XmlBlock");
ByteBuffer buf = ByteBuffer.allocate(16 * 1024).order(ByteOrder.LITTLE_ENDIAN);
Writer resStringPoolWriter = new Writer();
final SparseArray<Integer> resIds = new SparseArray<>();
final int[] maxAttrNameIndex = new int[] { 0 };
ResXMLTree_attrExt.Writer dummyStart = new ResXMLTree_attrExt.Writer(buf, resStringPoolWriter, null, "dummy") {
{
String packageName = resourceResolver.getPackageName();
for (Entry<Integer, String> entry : attrToValue.entrySet()) {
Integer attrId = entry.getKey();
String attrNs = "";
String attrName;
ResName attrResName = null;
String magicAttr = MAGIC_ATTRS.get(attrId);
if (magicAttr != null) {
attrId = null;
attrName = magicAttr;
} else {
String attrNameStr = resourceResolver.getResourceName(attrId);
attrResName = ResName.qualifyResName(attrNameStr, packageName, "attr");
attrNs = attrResName.packageName.equals("android") ? ANDROID_NS : AUTO_NS;
attrName = attrResName.name;
}
String value = entry.getValue();
DataType type;
int valueInt;
if (value == null || AttributeResource.isNull(value)) {
type = DataType.NULL;
valueInt = TypedValue.DATA_NULL_EMPTY;
} else if (AttributeResource.isResourceReference(value)) {
ResName resRef = AttributeResource.getResourceReference(value, packageName, null);
Integer valueResId = resourceResolver.getIdentifier(resRef.name, resRef.type, resRef.packageName);
if (valueResId == 0) {
throw new IllegalArgumentException("no such resource " + value + " while resolving value for " + (attrResName == null ? attrName : attrResName.getFullyQualifiedName()));
}
type = DataType.REFERENCE;
if (attrResName != null) {
value = "@" + valueResId;
}
valueInt = valueResId;
} else if (AttributeResource.isStyleReference(value)) {
ResName resRef = AttributeResource.getStyleReference(value, packageName, "attr");
Integer valueResId = resourceResolver.getIdentifier(resRef.name, resRef.type, resRef.packageName);
if (valueResId == 0) {
throw new IllegalArgumentException("no such attr " + value + " while resolving value for " + (attrResName == null ? attrName : attrResName.getFullyQualifiedName()));
}
type = DataType.ATTRIBUTE;
valueInt = valueResId;
} else if (attrResName == null) {
// class, id, or style
type = DataType.STRING;
valueInt = resStringPoolWriter.string(value);
} else {
TypedValue outValue = parse(attrId, attrResName, value, packageName);
type = DataType.fromCode(outValue.type);
value = (String) outValue.string;
if (type == DataType.STRING && outValue.data == 0) {
valueInt = resStringPoolWriter.string(value);
} else {
valueInt = outValue.data;
}
}
Res_value resValue = new Res_value(type.code(), valueInt);
int attrNameIndex = resStringPoolWriter.uniqueString(attrName);
attr(resStringPoolWriter.string(attrNs), attrNameIndex, resStringPoolWriter.string(value), resValue, attrNs + ":" + attrName);
if (attrId != null) {
resIds.put(attrNameIndex, attrId);
}
maxAttrNameIndex[0] = Math.max(maxAttrNameIndex[0], attrNameIndex);
}
}
};
ResXMLTree_endElementExt.Writer dummyEnd = new ResXMLTree_endElementExt.Writer(buf, resStringPoolWriter, null, "dummy");
int finalMaxAttrNameIndex = maxAttrNameIndex[0];
ResXMLTree_header.write(buf, resStringPoolWriter, () -> {
if (finalMaxAttrNameIndex > 0) {
ResChunk_header.write(buf, (short) RES_XML_RESOURCE_MAP_TYPE, () -> {
}, () -> {
// not particularly compact, but no big deal for our purposes...
for (int i = 0; i <= finalMaxAttrNameIndex; i++) {
Integer value = resIds.get(i);
buf.putInt(value == null ? 0 : value);
}
});
}
ResXMLTree_node.write(buf, RES_XML_START_ELEMENT_TYPE, dummyStart::write);
ResXMLTree_node.write(buf, RES_XML_END_ELEMENT_TYPE, dummyEnd::write);
});
int size = buf.position();
byte[] bytes = new byte[size];
// Cast to Buffer because generated covariant return type that returns ByteBuffer is not
// available on Java 8
((Buffer) buf).position(0);
buf.get(bytes, 0, size);
Object xmlBlockInstance = ReflectionHelpers.callConstructor(xmlBlockClass, ClassParameter.from(byte[].class, bytes));
AttributeSet parser = ReflectionHelpers.callInstanceMethod(xmlBlockClass, xmlBlockInstance, "newParser");
ReflectionHelpers.callInstanceMethod(parser, "next");
ReflectionHelpers.callInstanceMethod(parser, "next");
return parser;
}
use of org.robolectric.res.android.ResourceTypes.ResStringPool_header.Writer in project robolectric by robolectric.
the class ResStringPool method setToEmpty.
void setToEmpty() {
uninit();
ByteBuffer buf = ByteBuffer.allocate(16 * 1024).order(ByteOrder.LITTLE_ENDIAN);
Writer resStringPoolWriter = new Writer();
resStringPoolWriter.write(buf);
mOwnedData = new byte[buf.position()];
buf.position();
buf.get(mOwnedData);
ResStringPool_header header = new ResStringPool_header(buf, 0);
mSize = 0;
mEntries = null;
mStrings = 0;
mStringPoolSize = 0;
mEntryStyles = null;
mStyles = 0;
mStylePoolSize = 0;
mHeader = header;
}
Aggregations