| /* |
| * Copyright (C) 2007 Esmertec AG. |
| * Copyright (C) 2007 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.im.imps; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| |
| import org.xml.sax.Attributes; |
| import org.xml.sax.ContentHandler; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.SAXException; |
| |
| /* |
| * NOT thread-safe. Always use this in one thread. |
| */ |
| final class WbxmlParser { |
| private static final int BUFFER_SIZE = 1024; |
| |
| private ContentHandler mContentHandler; |
| private int mNativeParser; |
| private AttributesImpl atts; |
| |
| public WbxmlParser() { |
| atts = new AttributesImpl(); |
| mNativeParser = nativeCreate("UTF-8"); |
| if (mNativeParser == 0) { |
| throw new OutOfMemoryError(); |
| } |
| } |
| |
| @Override |
| protected void finalize() { |
| if (mNativeParser != 0) { |
| nativeRelease(mNativeParser); |
| } |
| } |
| |
| public void setContentHandler(ContentHandler contentHandler) { |
| mContentHandler = contentHandler; |
| } |
| |
| public void reset() { |
| if (mNativeParser != 0) { |
| nativeReset(mNativeParser); |
| } |
| atts.names = null; |
| atts.values = null; |
| mContentHandler = null; |
| } |
| |
| public void parse(InputSource in) throws ParserException, SAXException, IOException { |
| InputStream byteStream = in.getByteStream(); |
| byte[] buffer = new byte[BUFFER_SIZE]; |
| int length; |
| // FIXME: nativeParse should throw ParserException but the dalvik |
| // seems to have problem throwing non-system exceptions from JNI |
| // code. Use IAE for now and file a bug report for this. |
| try { |
| while ((length = byteStream.read(buffer)) != -1) { |
| nativeParse(mNativeParser, buffer, length, false); |
| } |
| nativeParse(mNativeParser, new byte[1], 0, true); |
| } catch (IllegalArgumentException e) { |
| throw new ParserException(e); |
| } |
| } |
| |
| void startElement(String name, String[] attrNames, String[] attrValues) |
| throws SAXException { |
| atts.names = attrNames; |
| atts.values = attrValues; |
| if(mContentHandler != null) { |
| mContentHandler.startElement("", name, name, atts); |
| } |
| } |
| |
| void endElement(String name) throws SAXException { |
| if(mContentHandler != null) { |
| mContentHandler.endElement("", name, name); |
| } |
| } |
| |
| void characters(char[] ch, int length) throws SAXException { |
| if(mContentHandler != null) { |
| mContentHandler.characters(ch, 0, length); |
| } |
| } |
| |
| static native void nativeStaticInitialize(); |
| |
| native int nativeCreate(String encoding); |
| |
| native void nativeRelease(int nativeParser); |
| |
| native void nativeReset(int nativeParser); |
| |
| // XXX: nativeParse should throw ParserException but the dalvik seems to |
| // have problem throwing non-system exceptions from JNI code. Use IAE |
| // for now and file a bug report for this. |
| native void nativeParse(int nativeParser, byte[] ch, int length, |
| boolean isEnd) throws IllegalArgumentException, SAXException, IOException; |
| |
| static { |
| try { |
| System.loadLibrary("wbxml_jni"); |
| nativeStaticInitialize(); |
| } catch (UnsatisfiedLinkError ule) { |
| System.err.println("WARNING: Could not load library libwbxml_jni.so"); |
| } |
| } |
| |
| static class AttributesImpl implements Attributes { |
| String[] names = null; |
| String[] values = null; |
| |
| public int getIndex(String qName) { |
| if(names == null) { |
| return -1; |
| } |
| for (int i = 0; i < names.length; i++) { |
| if (names[i].equals(qName)) { |
| return i; |
| } |
| } |
| return -1; |
| } |
| |
| public int getIndex(String uri, String localName) { |
| if(!"".equals(uri)) { |
| return -1; |
| } |
| return getIndex(localName); |
| } |
| |
| public int getLength() { |
| return names == null ? 0 : names.length; |
| } |
| |
| public String getLocalName(int index) { |
| if(index < 0 || index >= getLength()) { |
| return null; |
| } |
| return names[index]; |
| } |
| |
| public String getQName(int index) { |
| if(index < 0 || index >= getLength()) { |
| return null; |
| } |
| return names[index]; |
| } |
| |
| public String getType(int index) { |
| if(index < 0 || index >= getLength()) { |
| return null; |
| } |
| return "CDATA"; |
| } |
| |
| public String getType(String qName) { |
| return getIndex(qName) == -1 ? null : "CDATA"; |
| } |
| |
| public String getType(String uri, String localName) { |
| return getIndex(uri, localName) == -1 ? null : "CDATA"; |
| } |
| |
| public String getURI(int index) { |
| if(index < 0 || index >= getLength()) { |
| return null; |
| } |
| return ""; |
| } |
| |
| public String getValue(int index) { |
| if(index < 0 || index >= getLength()) { |
| return null; |
| } |
| return values[index]; |
| } |
| |
| public String getValue(String qName) { |
| int index = getIndex(qName); |
| return index == -1 ? null : values[index]; |
| } |
| |
| public String getValue(String uri, String localName) { |
| int index = getIndex(uri, localName); |
| return index == -1 ? null : values[index]; |
| } |
| } |
| } |