use of org.robolectric.res.android.ResourceTypes.ResTable_header in project robolectric by robolectric.
the class ResTable method addEmpty.
int addEmpty(final int cookie) {
Header header = new Header(this);
header.index = mHeaders.size();
header.cookie = cookie;
header.values.setToEmpty();
header.ownedData = new byte[ResTable_header.SIZEOF];
ByteBuffer buf = ByteBuffer.wrap(header.ownedData).order(ByteOrder.LITTLE_ENDIAN);
ResChunk_header.write(buf, (short) RES_TABLE_TYPE, () -> {
}, () -> {
});
ResTable_header resHeader = new ResTable_header(buf, 0);
// resHeader.header.type = RES_TABLE_TYPE;
// resHeader.header.headerSize = sizeof(ResTable_header);
// resHeader.header.size = sizeof(ResTable_header);
header.header = resHeader;
mHeaders.add(header);
return (mError = NO_ERROR);
}
use of org.robolectric.res.android.ResourceTypes.ResTable_header in project robolectric by robolectric.
the class ResTable method addInternal.
// status_t addInternal(const void* data, size_t size, const void* idmapData, size_t idmapDataSize,
// bool appAsLib, const int32_t cookie, bool copyData, bool isSystemAsset=false);
int addInternal(byte[] data, int dataSize, final Object idmapData, int idmapDataSize, boolean appAsLib, final int cookie, boolean copyData, boolean isSystemAsset) {
if (!isTruthy(data)) {
return NO_ERROR;
}
if (dataSize < ResTable_header.SIZEOF) {
ALOGE("Invalid data. Size(%d) is smaller than a ResTable_header(%d).", (int) dataSize, (int) ResTable_header.SIZEOF);
return UNKNOWN_ERROR;
}
Header header = new Header(this);
header.index = mHeaders.size();
header.cookie = cookie;
if (idmapData != NULL) {
header.resourceIDMap = new int[idmapDataSize / 4];
if (header.resourceIDMap == NULL) {
// delete header;
return (mError = NO_MEMORY);
}
// memcpy(header.resourceIDMap, idmapData, idmapDataSize);
// header.resourceIDMapSize = idmapDataSize;
}
mHeaders.add(header);
final boolean notDeviceEndian = htods((short) 0xf0) != 0xf0;
if (kDebugLoadTableNoisy) {
ALOGV("Adding resources to ResTable: data=%s, size=0x%x, cookie=%d, copy=%d " + "idmap=%s\n", data, dataSize, cookie, copyData, idmapData);
}
if (copyData || notDeviceEndian) {
// malloc(dataSize);
header.ownedData = data;
if (header.ownedData == NULL) {
return (mError = NO_MEMORY);
}
// memcpy(header.ownedData, data, dataSize);
data = header.ownedData;
}
ByteBuffer buf = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);
// header->header = (const ResTable_header*)data;
header.header = new ResTable_header(buf, 0);
header.size = dtohl(header.header.header.size);
if (kDebugLoadTableSuperNoisy) {
ALOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header.size, dtohl(header.header.header.size), header.header.header.size);
}
if (kDebugLoadTableNoisy) {
ALOGV("Loading ResTable @%s:\n", header.header);
}
if (dtohs(header.header.header.headerSize) > header.size || header.size > dataSize) {
ALOGW("Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\n", (int) dtohs(header.header.header.headerSize), (int) header.size, (int) dataSize);
return (mError = BAD_TYPE);
}
if (((dtohs(header.header.header.headerSize) | header.size) & 0x3) != 0) {
ALOGW("Bad resource table: header size 0x%x or total size 0x%x is not on an integer boundary\n", (int) dtohs(header.header.header.headerSize), (int) header.size);
return (mError = BAD_TYPE);
}
// header->dataEnd = ((const uint8_t*)header->header) + header->size;
header.dataEnd = header.size;
// Iterate through all chunks.
int curPackage = 0;
// const ResChunk_header* chunk =
// (const ResChunk_header*)(((const uint8_t*)header->header)
// + dtohs(header->header->header.headerSize));
ResChunk_header chunk = new ResChunk_header(buf, dtohs(header.header.header.headerSize));
while (chunk != null && (chunk.myOffset()) <= (header.dataEnd - ResChunk_header.SIZEOF) && (chunk.myOffset()) <= (header.dataEnd - dtohl(chunk.size))) {
int err = validate_chunk(chunk, ResChunk_header.SIZEOF, header.dataEnd, "ResTable");
if (err != NO_ERROR) {
return (mError = err);
}
if (kDebugTableNoisy) {
ALOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%s\n", dtohs(chunk.type), dtohs(chunk.headerSize), dtohl(chunk.size), (Object) ((chunk.myOffset()) - (header.header.myOffset())));
}
final int csize = dtohl(chunk.size);
final int ctype = dtohs(chunk.type);
if (ctype == RES_STRING_POOL_TYPE) {
if (header.values.getError() != NO_ERROR) {
// Only use the first string chunk; ignore any others that
// may appear.
err = header.values.setTo(chunk.myBuf(), chunk.myOffset(), csize, false);
if (err != NO_ERROR) {
return (mError = err);
}
} else {
ALOGW("Multiple string chunks found in resource table.");
}
} else if (ctype == RES_TABLE_PACKAGE_TYPE) {
if (curPackage >= dtohl(header.header.packageCount)) {
ALOGW("More package chunks were found than the %d declared in the header.", dtohl(header.header.packageCount));
return (mError = BAD_TYPE);
}
if (parsePackage(new ResTable_package(chunk.myBuf(), chunk.myOffset()), header, appAsLib, isSystemAsset) != NO_ERROR) {
return mError;
}
curPackage++;
} else {
ALOGW("Unknown chunk type 0x%x in table at 0x%x.\n", ctype, (chunk.myOffset()) - (header.header.myOffset()));
}
chunk = chunk.myOffset() + csize < header.dataEnd ? new ResChunk_header(chunk.myBuf(), chunk.myOffset() + csize) : null;
}
if (curPackage < dtohl(header.header.packageCount)) {
ALOGW("Fewer package chunks (%d) were found than the %d declared in the header.", (int) curPackage, dtohl(header.header.packageCount));
return (mError = BAD_TYPE);
}
mError = header.values.getError();
if (mError != NO_ERROR) {
ALOGW("No string values found in resource table!");
}
if (kDebugTableNoisy) {
ALOGV("Returning from add with mError=%d\n", mError);
}
return mError;
}
use of org.robolectric.res.android.ResourceTypes.ResTable_header in project robolectric by robolectric.
the class LoadedArsc method LoadTable.
boolean LoadTable(Chunk chunk, LoadedIdmap loaded_idmap, boolean load_as_shared_library) {
// ResTable_header header = chunk.header<ResTable_header>();
ResTable_header header = chunk.asResTable_header();
if (header == null) {
logError("RES_TABLE_TYPE too small.");
return false;
}
int package_count = dtohl(header.packageCount);
int packages_seen = 0;
// packages_.reserve(package_count);
Chunk.Iterator iter = new Iterator(chunk.data_ptr(), chunk.data_size());
while (iter.HasNext()) {
Chunk child_chunk = iter.Next();
switch(child_chunk.type()) {
case RES_STRING_POOL_TYPE:
// Only use the first string pool. Ignore others.
if (global_string_pool_.getError() == NO_INIT) {
ResStringPool_header resStringPool_header = child_chunk.asResStringPool_header();
int err = global_string_pool_.setTo(resStringPool_header.myBuf(), resStringPool_header.myOffset(), child_chunk.size(), false);
if (err != NO_ERROR) {
logError("RES_STRING_POOL_TYPE corrupt.");
return false;
}
} else {
logWarning("Multiple RES_STRING_POOL_TYPEs found in RES_TABLE_TYPE.");
}
break;
case RES_TABLE_PACKAGE_TYPE:
{
if (packages_seen + 1 > package_count) {
logError("More package chunks were found than the " + package_count + " declared in the header.");
return false;
}
packages_seen++;
LoadedPackage loaded_package = LoadedPackage.Load(child_chunk, loaded_idmap, system_, load_as_shared_library);
if (!isTruthy(loaded_package)) {
return false;
}
packages_.add(loaded_package);
}
break;
default:
logWarning(String.format("Unknown chunk type '%02x'.", chunk.type()));
break;
}
}
if (iter.HadError()) {
logError(iter.GetLastError());
if (iter.HadFatalError()) {
return false;
}
}
return true;
}
Aggregations