Search in sources :

Example 1 with ResXMLTree_node

use of org.robolectric.res.android.ResourceTypes.ResXMLTree_node in project robolectric by robolectric.

the class ResXMLParser method nextNode.

int nextNode() {
    if (mEventCode < 0) {
        return mEventCode;
    }
    do {
        int nextOffset = mCurNode.myOffset() + dtohl(mCurNode.header.size);
        if (nextOffset >= mTree.mDataLen) {
            mCurNode = null;
            return (mEventCode = END_DOCUMENT);
        }
        // final ResXMLTree_node next = (ResXMLTree_node)
        // (((final int8_t*)mCurNode) + dtohl(mCurNode.header.size));
        ResXMLTree_node next = new ResXMLTree_node(mTree.mBuffer.buf, nextOffset);
        if (kDebugXMLNoisy) {
            ALOGI("Next node: prev=%s, next=%s\n", mCurNode, next);
        }
        if (next.myOffset() >= mTree.mDataLen) {
            mCurNode = null;
            return (mEventCode = END_DOCUMENT);
        }
        if (mTree.validateNode(next) != NO_ERROR) {
            mCurNode = null;
            return (mEventCode = BAD_DOCUMENT);
        }
        mCurNode = next;
        final int headerSize = dtohs(next.header.headerSize);
        final int totalSize = dtohl(next.header.size);
        mCurExt = next.myOffset() + headerSize;
        int minExtSize = 0;
        int eventCode = dtohs(next.header.type);
        switch((mEventCode = eventCode)) {
            case RES_XML_START_NAMESPACE_TYPE:
            case RES_XML_END_NAMESPACE_TYPE:
                minExtSize = SIZEOF_RESXMLTREE_NAMESPACE_EXT;
                break;
            case RES_XML_START_ELEMENT_TYPE:
                minExtSize = SIZEOF_RESXMLTREE_ATTR_EXT;
                break;
            case RES_XML_END_ELEMENT_TYPE:
                minExtSize = ResXMLTree_endElementExt.SIZEOF;
                break;
            case RES_XML_CDATA_TYPE:
                minExtSize = SIZEOF_RESXMLTREE_CDATA_EXT;
                break;
            default:
                ALOGW("Unknown XML block: header type %d in node at %d\n", (int) dtohs(next.header.type), (next.myOffset() - mTree.mHeader.myOffset()));
                continue;
        }
        if ((totalSize - headerSize) < minExtSize) {
            ALOGW("Bad XML block: header type 0x%x in node at 0x%x has size %d, need %d\n", (int) dtohs(next.header.type), (next.myOffset() - mTree.mHeader.myOffset()), (int) (totalSize - headerSize), (int) minExtSize);
            return (mEventCode = BAD_DOCUMENT);
        }
        return eventCode;
    } while (true);
}
Also used : ResXMLTree_node(org.robolectric.res.android.ResourceTypes.ResXMLTree_node)

Example 2 with ResXMLTree_node

use of org.robolectric.res.android.ResourceTypes.ResXMLTree_node in project robolectric by robolectric.

the class ResXMLTree method setTo.

public int setTo(byte[] data, int size, boolean copyData) {
    uninit();
    mParser.mEventCode = START_DOCUMENT;
    if (!isTruthy(data) || !isTruthy(size)) {
        return (mError = BAD_TYPE);
    }
    if (copyData) {
        mOwnedData = new byte[size];
        // if (mOwnedData == null) {
        // return (mError=NO_MEMORY);
        // }
        // memcpy(mOwnedData, data, size);
        System.arraycopy(data, 0, mOwnedData, 0, size);
        data = mOwnedData;
    }
    mBuffer = new XmlBuffer(data);
    mHeader = new ResXMLTree_header(mBuffer.buf, 0);
    mSize = dtohl(mHeader.header.size);
    if (dtohs(mHeader.header.headerSize) > mSize || mSize > size) {
        ALOGW("Bad XML block: header size %d or total size %d is larger than data size %d\n", (int) dtohs(mHeader.header.headerSize), (int) dtohl(mHeader.header.size), (int) size);
        mError = BAD_TYPE;
        mParser.restart();
        return mError;
    }
    // mDataEnd = ((final uint8_t*)mHeader) + mSize;
    mDataLen = mSize;
    mStrings.uninit();
    mRootNode = null;
    mResIds = null;
    mNumResIds = 0;
    // First look for a couple interesting chunks: the string block
    // and first XML node.
    ResChunk_header chunk = // (final ResChunk_header*)(((final uint8_t*)mHeader) + dtohs(mHeader.header.headerSize));
    new ResChunk_header(mBuffer.buf, mHeader.header.headerSize);
    ResChunk_header lastChunk = chunk;
    while (chunk.myOffset() < /*((final uint8_t*)chunk)*/
    (mDataLen - ResChunk_header.SIZEOF) && chunk.myOffset() < /*((final uint8_t*)chunk)*/
    (mDataLen - dtohl(chunk.size))) {
        int err = validate_chunk(chunk, ResChunk_header.SIZEOF, /*sizeof(ResChunk_header)*/
        mDataLen, "XML");
        if (err != NO_ERROR) {
            mError = err;
            // goto done;
            mParser.restart();
            return mError;
        }
        final short type = dtohs(chunk.type);
        final int size1 = dtohl(chunk.size);
        if (kDebugXMLNoisy) {
        // System.out.println(String.format("Scanning @ %s: type=0x%x, size=0x%zx\n",
        // (void*)(((uintptr_t)chunk)-((uintptr_t)mHeader)), type, size1);
        }
        if (type == RES_STRING_POOL_TYPE) {
            mStrings.setTo(mBuffer.buf, chunk.myOffset(), size, false);
        } else if (type == RES_XML_RESOURCE_MAP_TYPE) {
            // mResIds = (final int*)
            // (((final uint8_t*)chunk)+dtohs(chunk.headerSize()));
            mNumResIds = (dtohl(chunk.size) - dtohs(chunk.headerSize)) / SIZEOF_INT;
            mResIds = new int[mNumResIds];
            for (int i = 0; i < mNumResIds; i++) {
                mResIds[i] = mBuffer.buf.getInt(chunk.myOffset() + chunk.headerSize + i * SIZEOF_INT);
            }
        } else if (type >= RES_XML_FIRST_CHUNK_TYPE && type <= RES_XML_LAST_CHUNK_TYPE) {
            if (validateNode(new ResXMLTree_node(mBuffer.buf, chunk)) != NO_ERROR) {
                mError = BAD_TYPE;
                // goto done;
                mParser.restart();
                return mError;
            }
            mParser.mCurNode = new ResXMLTree_node(mBuffer.buf, lastChunk.myOffset());
            if (mParser.nextNode() == BAD_DOCUMENT) {
                mError = BAD_TYPE;
                // goto done;
                mParser.restart();
                return mError;
            }
            mRootNode = mParser.mCurNode;
            mRootExt = mParser.mCurExt;
            mRootCode = mParser.mEventCode;
            break;
        } else {
            if (kDebugXMLNoisy) {
                System.out.println("Skipping unknown chunk!\n");
            }
        }
        lastChunk = chunk;
        // chunk = (final ResChunk_header*)
        // (((final uint8_t*)chunk) + size1);
        chunk = new ResChunk_header(mBuffer.buf, chunk.myOffset() + size1);
    }
    if (mRootNode == null) {
        ALOGW("Bad XML block: no root element node found\n");
        mError = BAD_TYPE;
        // goto done;
        mParser.restart();
        return mError;
    }
    mError = mStrings.getError();
    done: mParser.restart();
    return mError;
}
Also used : ResXMLTree_header(org.robolectric.res.android.ResourceTypes.ResXMLTree_header) ResXMLTree_node(org.robolectric.res.android.ResourceTypes.ResXMLTree_node) ResChunk_header(org.robolectric.res.android.ResourceTypes.ResChunk_header)

Aggregations

ResXMLTree_node (org.robolectric.res.android.ResourceTypes.ResXMLTree_node)2 ResChunk_header (org.robolectric.res.android.ResourceTypes.ResChunk_header)1 ResXMLTree_header (org.robolectric.res.android.ResourceTypes.ResXMLTree_header)1