Search in sources :

Example 1 with ResTable_header

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);
}
Also used : ResTable_header(org.robolectric.res.android.ResourceTypes.ResTable_header) ByteBuffer(java.nio.ByteBuffer)

Example 2 with ResTable_header

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;
}
Also used : ResTable_header(org.robolectric.res.android.ResourceTypes.ResTable_header) ResTable_package(org.robolectric.res.android.ResourceTypes.ResTable_package) ResChunk_header(org.robolectric.res.android.ResourceTypes.ResChunk_header) ByteBuffer(java.nio.ByteBuffer)

Example 3 with ResTable_header

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;
}
Also used : ResTable_header(org.robolectric.res.android.ResourceTypes.ResTable_header) Iterator(org.robolectric.res.android.Chunk.Iterator) ResStringPool_header(org.robolectric.res.android.ResourceTypes.ResStringPool_header) Iterator(org.robolectric.res.android.Chunk.Iterator)

Aggregations

ResTable_header (org.robolectric.res.android.ResourceTypes.ResTable_header)3 ByteBuffer (java.nio.ByteBuffer)2 Iterator (org.robolectric.res.android.Chunk.Iterator)1 ResChunk_header (org.robolectric.res.android.ResourceTypes.ResChunk_header)1 ResStringPool_header (org.robolectric.res.android.ResourceTypes.ResStringPool_header)1 ResTable_package (org.robolectric.res.android.ResourceTypes.ResTable_package)1