19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.content.res;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinskiimport android.annotation.Nullable;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.TypedValue;
212269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackborn
222269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport com.android.internal.util.XmlUtils;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2432995223a85a3b774789091d97987dfacc1e9ef3John Reckimport dalvik.annotation.optimization.FastNative;
2532995223a85a3b774789091d97987dfacc1e9ef3John Reck
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.Reader;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Wrapper around a compiled XML file.
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
37bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinskifinal class XmlBlock implements AutoCloseable {
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final boolean DEBUG=false;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public XmlBlock(byte[] data) {
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAssets = null;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNative = nativeCreate(data, 0, data.length);
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStrings = new StringBlock(nativeGetStringBlock(mNative), false);
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public XmlBlock(byte[] data, int offset, int size) {
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAssets = null;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNative = nativeCreate(data, offset, size);
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStrings = new StringBlock(nativeGetStringBlock(mNative), false);
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski    @Override
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void close() {
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (this) {
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mOpen) {
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOpen = false;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                decOpenCountLocked();
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void decOpenCountLocked() {
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOpenCount--;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mOpenCount == 0) {
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            nativeDestroy(mNative);
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mAssets != null) {
67c3b91fd26a940f8cee54888f91b490cb1768b03cDianne Hackborn                mAssets.xmlBlockGone(hashCode());
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public XmlResourceParser newParser() {
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (this) {
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mNative != 0) {
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return new Parser(nativeCreateParseState(mNative), this);
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ final class Parser implements XmlResourceParser {
82896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat        Parser(long parseState, XmlBlock block) {
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mParseState = parseState;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mBlock = block;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            block.mOpenCount++;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setFeature(String name, boolean state) throws XmlPullParserException {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) {
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name) && state) {
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new XmlPullParserException("Unsupported feature: " + name);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean getFeature(String name) {
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (FEATURE_PROCESS_NAMESPACES.equals(name)) {
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) {
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setProperty(String name, Object value) throws XmlPullParserException {
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new XmlPullParserException("setProperty() not supported");
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Object getProperty(String name) {
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setInput(Reader in) throws XmlPullParserException {
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new XmlPullParserException("setInput() not supported");
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setInput(InputStream inputStream, String inputEncoding) throws XmlPullParserException {
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new XmlPullParserException("setInput() not supported");
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void defineEntityReplacementText(String entityName, String replacementText) throws XmlPullParserException {
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new XmlPullParserException("defineEntityReplacementText() not supported");
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getNamespacePrefix(int pos) throws XmlPullParserException {
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new XmlPullParserException("getNamespacePrefix() not supported");
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getInputEncoding() {
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getNamespace(String prefix) {
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("getNamespace() not supported");
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getNamespaceCount(int depth) throws XmlPullParserException {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new XmlPullParserException("getNamespaceCount() not supported");
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getPositionDescription() {
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "Binary XML file line #" + getLineNumber();
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getNamespaceUri(int pos) throws XmlPullParserException {
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new XmlPullParserException("getNamespaceUri() not supported");
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getColumnNumber() {
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -1;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getDepth() {
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDepth;
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getText() {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int id = nativeGetText(mParseState);
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return id >= 0 ? mStrings.get(id).toString() : null;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getLineNumber() {
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return nativeGetLineNumber(mParseState);
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getEventType() throws XmlPullParserException {
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mEventType;
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean isWhitespace() throws XmlPullParserException {
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // whitespace was stripped by aapt.
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getPrefix() {
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("getPrefix not supported");
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public char[] getTextCharacters(int[] holderForStartAndLength) {
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String txt = getText();
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char[] chars = null;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (txt != null) {
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                holderForStartAndLength[0] = 0;
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                holderForStartAndLength[1] = txt.length();
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                chars = new char[txt.length()];
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                txt.getChars(0, txt.length(), chars, 0);
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return chars;
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getNamespace() {
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int id = nativeGetNamespace(mParseState);
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return id >= 0 ? mStrings.get(id).toString() : "";
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getName() {
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int id = nativeGetName(mParseState);
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return id >= 0 ? mStrings.get(id).toString() : null;
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getAttributeNamespace(int index) {
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int id = nativeGetAttributeNamespace(mParseState, index);
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) System.out.println("getAttributeNamespace of " + index + " = " + id);
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (id >= 0) return mStrings.get(id).toString();
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else if (id == -1) return "";
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IndexOutOfBoundsException(String.valueOf(index));
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getAttributeName(int index) {
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int id = nativeGetAttributeName(mParseState, index);
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) System.out.println("getAttributeName of " + index + " = " + id);
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (id >= 0) return mStrings.get(id).toString();
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IndexOutOfBoundsException(String.valueOf(index));
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getAttributePrefix(int index) {
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("getAttributePrefix not supported");
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean isEmptyElementTag() throws XmlPullParserException {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // XXX Need to detect this.
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getAttributeCount() {
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mEventType == START_TAG ? nativeGetAttributeCount(mParseState) : -1;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getAttributeValue(int index) {
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int id = nativeGetAttributeStringValue(mParseState, index);
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) System.out.println("getAttributeValue of " + index + " = " + id);
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (id >= 0) return mStrings.get(id).toString();
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // May be some other type...  check and try to convert if so.
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int t = nativeGetAttributeDataType(mParseState, index);
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == TypedValue.TYPE_NULL) {
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IndexOutOfBoundsException(String.valueOf(index));
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int v = nativeGetAttributeData(mParseState, index);
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return TypedValue.coerceToString(t, v);
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getAttributeType(int index) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "CDATA";
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean isAttributeDefault(int index) {
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int nextToken() throws XmlPullParserException,IOException {
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return next();
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getAttributeValue(String namespace, String name) {
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int idx = nativeGetAttributeIndex(mParseState, namespace, name);
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (idx >= 0) {
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (DEBUG) System.out.println("getAttributeName of "
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + namespace + ":" + name + " index = " + idx);
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (DEBUG) System.out.println(
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "Namespace=" + getAttributeNamespace(idx)
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + "Name=" + getAttributeName(idx)
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + ", Value=" + getAttributeValue(idx));
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getAttributeValue(idx);
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int next() throws XmlPullParserException,IOException {
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mStarted) {
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mStarted = true;
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return START_DOCUMENT;
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mParseState == 0) {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return END_DOCUMENT;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int ev = nativeNext(mParseState);
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mDecNextDepth) {
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDepth--;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDecNextDepth = false;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (ev) {
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case START_TAG:
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDepth++;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case END_TAG:
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDecNextDepth = true;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mEventType = ev;
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ev == END_DOCUMENT) {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Automatically close the parse when we reach the end of
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // a document, since the standard XmlPullParser interface
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // doesn't have such an API so most clients will leave us
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // dangling.
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                close();
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ev;
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void require(int type, String namespace, String name) throws XmlPullParserException,IOException {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (type != getEventType()
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || (namespace != null && !namespace.equals( getNamespace () ) )
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || (name != null && !name.equals( getName() ) ) )
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new XmlPullParserException( "expected "+ TYPES[ type ]+getPositionDescription());
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String nextText() throws XmlPullParserException,IOException {
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if(getEventType() != START_TAG) {
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               throw new XmlPullParserException(
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 getPositionDescription()
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 + ": parser must be on START_TAG to read next text", this, null);
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int eventType = next();
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if(eventType == TEXT) {
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               String result = getText();
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               eventType = next();
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               if(eventType != END_TAG) {
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 throw new XmlPullParserException(
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    getPositionDescription()
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ": event TEXT it must be immediately followed by END_TAG", this, null);
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return result;
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if(eventType == END_TAG) {
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               return "";
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               throw new XmlPullParserException(
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 getPositionDescription()
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 + ": parser must be on START_TAG or TEXT to read text", this, null);
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int nextTag() throws XmlPullParserException,IOException {
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int eventType = next();
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if(eventType == TEXT && isWhitespace()) {   // skip whitespace
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               eventType = next();
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (eventType != START_TAG && eventType != END_TAG) {
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               throw new XmlPullParserException(
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   getPositionDescription()
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   + ": expected start or end tag", this, null);
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return eventType;
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getAttributeNameResource(int index) {
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return nativeGetAttributeResource(mParseState, index);
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getAttributeListValue(String namespace, String attribute,
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String[] options, int defaultValue) {
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int idx = nativeGetAttributeIndex(mParseState, namespace, attribute);
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (idx >= 0) {
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getAttributeListValue(idx, options, defaultValue);
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return defaultValue;
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean getAttributeBooleanValue(String namespace, String attribute,
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                boolean defaultValue) {
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int idx = nativeGetAttributeIndex(mParseState, namespace, attribute);
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (idx >= 0) {
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getAttributeBooleanValue(idx, defaultValue);
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return defaultValue;
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getAttributeResourceValue(String namespace, String attribute,
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int defaultValue) {
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int idx = nativeGetAttributeIndex(mParseState, namespace, attribute);
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (idx >= 0) {
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getAttributeResourceValue(idx, defaultValue);
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return defaultValue;
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getAttributeIntValue(String namespace, String attribute,
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int defaultValue) {
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int idx = nativeGetAttributeIndex(mParseState, namespace, attribute);
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (idx >= 0) {
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getAttributeIntValue(idx, defaultValue);
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return defaultValue;
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getAttributeUnsignedIntValue(String namespace, String attribute,
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                int defaultValue)
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int idx = nativeGetAttributeIndex(mParseState, namespace, attribute);
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (idx >= 0) {
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getAttributeUnsignedIntValue(idx, defaultValue);
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return defaultValue;
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public float getAttributeFloatValue(String namespace, String attribute,
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                float defaultValue) {
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int idx = nativeGetAttributeIndex(mParseState, namespace, attribute);
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (idx >= 0) {
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getAttributeFloatValue(idx, defaultValue);
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return defaultValue;
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getAttributeListValue(int idx,
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String[] options, int defaultValue) {
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int t = nativeGetAttributeDataType(mParseState, idx);
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int v = nativeGetAttributeData(mParseState, idx);
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == TypedValue.TYPE_STRING) {
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return XmlUtils.convertValueToList(
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mStrings.get(v), options, defaultValue);
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return v;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean getAttributeBooleanValue(int idx,
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                boolean defaultValue) {
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int t = nativeGetAttributeDataType(mParseState, idx);
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Note: don't attempt to convert any other types, because
382de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski            // we want to count on aapt doing the conversion for us.
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t >= TypedValue.TYPE_FIRST_INT &&
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                t <= TypedValue.TYPE_LAST_INT) {
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return nativeGetAttributeData(mParseState, idx) != 0;
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return defaultValue;
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getAttributeResourceValue(int idx, int defaultValue) {
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int t = nativeGetAttributeDataType(mParseState, idx);
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Note: don't attempt to convert any other types, because
392de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski            // we want to count on aapt doing the conversion for us.
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == TypedValue.TYPE_REFERENCE) {
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return nativeGetAttributeData(mParseState, idx);
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return defaultValue;
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getAttributeIntValue(int idx, int defaultValue) {
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int t = nativeGetAttributeDataType(mParseState, idx);
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Note: don't attempt to convert any other types, because
401de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski            // we want to count on aapt doing the conversion for us.
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t >= TypedValue.TYPE_FIRST_INT &&
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                t <= TypedValue.TYPE_LAST_INT) {
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return nativeGetAttributeData(mParseState, idx);
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return defaultValue;
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getAttributeUnsignedIntValue(int idx, int defaultValue) {
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int t = nativeGetAttributeDataType(mParseState, idx);
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Note: don't attempt to convert any other types, because
411de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski            // we want to count on aapt doing the conversion for us.
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t >= TypedValue.TYPE_FIRST_INT &&
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                t <= TypedValue.TYPE_LAST_INT) {
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return nativeGetAttributeData(mParseState, idx);
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return defaultValue;
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public float getAttributeFloatValue(int idx, float defaultValue) {
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int t = nativeGetAttributeDataType(mParseState, idx);
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Note: don't attempt to convert any other types, because
421de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski            // we want to count on aapt doing the conversion for us.
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == TypedValue.TYPE_FLOAT) {
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return Float.intBitsToFloat(
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    nativeGetAttributeData(mParseState, idx));
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("not a float!");
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getIdAttribute() {
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int id = nativeGetIdAttribute(mParseState);
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return id >= 0 ? mStrings.get(id).toString() : null;
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getClassAttribute() {
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int id = nativeGetClassAttribute(mParseState);
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return id >= 0 ? mStrings.get(id).toString() : null;
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getIdAttributeResourceValue(int defaultValue) {
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //todo: create and use native method
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return getAttributeResourceValue(null, "id", defaultValue);
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getStyleAttribute() {
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return nativeGetStyleAttribute(mParseState);
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void close() {
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (mBlock) {
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mParseState != 0) {
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    nativeDestroyParseState(mParseState);
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mParseState = 0;
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mBlock.decOpenCountLocked();
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        protected void finalize() throws Throwable {
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            close();
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*package*/ final CharSequence getPooledString(int id) {
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mStrings.get(id);
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
465896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat        /*package*/ long mParseState;
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final XmlBlock mBlock;
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private boolean mStarted = false;
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private boolean mDecNextDepth = false;
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private int mDepth = 0;
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private int mEventType = START_DOCUMENT;
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void finalize() throws Throwable {
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        close();
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create from an existing xml block native object.  This is
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * -extremely- dangerous -- only use it if you absolutely know what you
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  are doing!  The given native object must exist for the entire lifetime
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  of this newly creating XmlBlock.
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
483bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski    XmlBlock(@Nullable AssetManager assets, long xmlBlock) {
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAssets = assets;
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNative = xmlBlock;
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStrings = new StringBlock(nativeGetStringBlock(xmlBlock), false);
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489bebfcc46a249a70af04bc18490a897888a142fb8Adam Lesinski    private @Nullable final AssetManager mAssets;
490896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private final long mNative;
49160201f2b4ee3fcf222310b5bf91d1d150470cab7Christopher Tate    /*package*/ final StringBlock mStrings;
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mOpen = true;
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mOpenCount = 1;
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
495896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native long nativeCreate(byte[] data,
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 int offset,
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 int size);
498896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native long nativeGetStringBlock(long obj);
499896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native long nativeCreateParseState(long obj);
50032995223a85a3b774789091d97987dfacc1e9ef3John Reck    private static final native void nativeDestroyParseState(long state);
50132995223a85a3b774789091d97987dfacc1e9ef3John Reck    private static final native void nativeDestroy(long obj);
50232995223a85a3b774789091d97987dfacc1e9ef3John Reck
50332995223a85a3b774789091d97987dfacc1e9ef3John Reck    // ----------- @FastNative ------------------
50432995223a85a3b774789091d97987dfacc1e9ef3John Reck
50532995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
506896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    /*package*/ static final native int nativeNext(long state);
50732995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
508896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native int nativeGetNamespace(long state);
50932995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
510896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    /*package*/ static final native int nativeGetName(long state);
51132995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
512896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native int nativeGetText(long state);
51332995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
514896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native int nativeGetLineNumber(long state);
51532995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
516896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native int nativeGetAttributeCount(long state);
51732995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
518896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native int nativeGetAttributeNamespace(long state, int idx);
51932995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
520896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native int nativeGetAttributeName(long state, int idx);
52132995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
522896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native int nativeGetAttributeResource(long state, int idx);
52332995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
524896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native int nativeGetAttributeDataType(long state, int idx);
52532995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
526896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native int nativeGetAttributeData(long state, int idx);
52732995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
528896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native int nativeGetAttributeStringValue(long state, int idx);
52932995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
530896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native int nativeGetIdAttribute(long state);
53132995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
532896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native int nativeGetClassAttribute(long state);
53332995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
534896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native int nativeGetStyleAttribute(long state);
53532995223a85a3b774789091d97987dfacc1e9ef3John Reck    @FastNative
536896043d67d3ac75760bd99db8a1561e31ebee1e1Ashok Bhat    private static final native int nativeGetAttributeIndex(long state, String namespace, String name);
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
538