1087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor/* 2087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * Copyright (C) 2006 The Android Open Source Project 3087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * 4087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * Licensed under the Apache License, Version 2.0 (the "License"); 5087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * you may not use this file except in compliance with the License. 6087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * You may obtain a copy of the License at 7087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * 8087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * http://www.apache.org/licenses/LICENSE-2.0 9087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * 10087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * Unless required by applicable law or agreed to in writing, software 11087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * distributed under the License is distributed on an "AS IS" BASIS, 12087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * See the License for the specific language governing permissions and 14087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * limitations under the License. 15087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor */ 16087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 172269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornpackage com.android.internal.util; 18087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 19087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylorimport org.xmlpull.v1.XmlSerializer; 20087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 21087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylorimport java.io.IOException; 22087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylorimport java.io.OutputStream; 23087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylorimport java.io.OutputStreamWriter; 24087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylorimport java.io.UnsupportedEncodingException; 25087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylorimport java.io.Writer; 26087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylorimport java.nio.ByteBuffer; 27087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylorimport java.nio.CharBuffer; 28087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylorimport java.nio.charset.Charset; 29087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylorimport java.nio.charset.CharsetEncoder; 30087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylorimport java.nio.charset.CoderResult; 313ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onukiimport java.nio.charset.CodingErrorAction; 32087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylorimport java.nio.charset.IllegalCharsetNameException; 33087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylorimport java.nio.charset.UnsupportedCharsetException; 34087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 35087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor/** 36087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * This is a quick and dirty implementation of XmlSerializer that isn't horribly 37087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * painfully slow like the normal one. It only does what is needed for the 38087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor * specific XML files being written with it. 39087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor */ 40087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylorpublic class FastXmlSerializer implements XmlSerializer { 41087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private static final String ESCAPE_TABLE[] = new String[] { 423ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onuki "�", "", "", "", "", "", "", "", // 0-7 433ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onuki "", "	", " ", "", "", " ", "", "", // 8-15 443ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onuki "", "", "", "", "", "", "", "", // 16-23 453ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onuki "", "", "", "", "", "", "", "", // 24-31 463ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onuki null, null, """, null, null, null, "&", null, // 32-39 473ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onuki null, null, null, null, null, null, null, null, // 40-47 483ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onuki null, null, null, null, null, null, null, null, // 48-55 493ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onuki null, null, null, null, "<", null, ">", null, // 56-63 50087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor }; 51087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 5213e11e83f66c374637839548f3c871f6df3b6868Christopher Tate private static final int DEFAULT_BUFFER_LEN = 32*1024; 53087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 548a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn private static String sSpace = " "; 558a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn 5613e11e83f66c374637839548f3c871f6df3b6868Christopher Tate private final int mBufferLen; 5713e11e83f66c374637839548f3c871f6df3b6868Christopher Tate private final char[] mText; 58087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private int mPos; 59087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 60087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private Writer mWriter; 61087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 62087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private OutputStream mOutputStream; 63087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private CharsetEncoder mCharset; 6413e11e83f66c374637839548f3c871f6df3b6868Christopher Tate private ByteBuffer mBytes; 65087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 668a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn private boolean mIndent = false; 67087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private boolean mInTag; 68087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 698a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn private int mNesting = 0; 708a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn private boolean mLineStart = true; 718a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn 7213e11e83f66c374637839548f3c871f6df3b6868Christopher Tate public FastXmlSerializer() { 7313e11e83f66c374637839548f3c871f6df3b6868Christopher Tate this(DEFAULT_BUFFER_LEN); 7413e11e83f66c374637839548f3c871f6df3b6868Christopher Tate } 7513e11e83f66c374637839548f3c871f6df3b6868Christopher Tate 7613e11e83f66c374637839548f3c871f6df3b6868Christopher Tate /** 7713e11e83f66c374637839548f3c871f6df3b6868Christopher Tate * Allocate a FastXmlSerializer with the given internal output buffer size. If the 7813e11e83f66c374637839548f3c871f6df3b6868Christopher Tate * size is zero or negative, then the default buffer size will be used. 7913e11e83f66c374637839548f3c871f6df3b6868Christopher Tate * 8013e11e83f66c374637839548f3c871f6df3b6868Christopher Tate * @param bufferSize Size in bytes of the in-memory output buffer that the writer will use. 8113e11e83f66c374637839548f3c871f6df3b6868Christopher Tate */ 8213e11e83f66c374637839548f3c871f6df3b6868Christopher Tate public FastXmlSerializer(int bufferSize) { 8313e11e83f66c374637839548f3c871f6df3b6868Christopher Tate mBufferLen = (bufferSize > 0) ? bufferSize : DEFAULT_BUFFER_LEN; 8413e11e83f66c374637839548f3c871f6df3b6868Christopher Tate mText = new char[mBufferLen]; 8513e11e83f66c374637839548f3c871f6df3b6868Christopher Tate mBytes = ByteBuffer.allocate(mBufferLen); 8613e11e83f66c374637839548f3c871f6df3b6868Christopher Tate } 8713e11e83f66c374637839548f3c871f6df3b6868Christopher Tate 88087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private void append(char c) throws IOException { 89087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int pos = mPos; 9013e11e83f66c374637839548f3c871f6df3b6868Christopher Tate if (pos >= (mBufferLen-1)) { 91087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor flush(); 92087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor pos = mPos; 93087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 94087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mText[pos] = c; 95087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mPos = pos+1; 96087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 97087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 98087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private void append(String str, int i, final int length) throws IOException { 9913e11e83f66c374637839548f3c871f6df3b6868Christopher Tate if (length > mBufferLen) { 100087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor final int end = i + length; 101087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor while (i < end) { 10213e11e83f66c374637839548f3c871f6df3b6868Christopher Tate int next = i + mBufferLen; 10313e11e83f66c374637839548f3c871f6df3b6868Christopher Tate append(str, i, next<end ? mBufferLen : (end-i)); 104087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor i = next; 105087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 106087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return; 107087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 108087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int pos = mPos; 10913e11e83f66c374637839548f3c871f6df3b6868Christopher Tate if ((pos+length) > mBufferLen) { 110087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor flush(); 111087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor pos = mPos; 112087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 113087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor str.getChars(i, i+length, mText, pos); 114087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mPos = pos + length; 115087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 116087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 117087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private void append(char[] buf, int i, final int length) throws IOException { 11813e11e83f66c374637839548f3c871f6df3b6868Christopher Tate if (length > mBufferLen) { 119087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor final int end = i + length; 120087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor while (i < end) { 12113e11e83f66c374637839548f3c871f6df3b6868Christopher Tate int next = i + mBufferLen; 12213e11e83f66c374637839548f3c871f6df3b6868Christopher Tate append(buf, i, next<end ? mBufferLen : (end-i)); 123087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor i = next; 124087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 125087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return; 126087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 127087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int pos = mPos; 12813e11e83f66c374637839548f3c871f6df3b6868Christopher Tate if ((pos+length) > mBufferLen) { 129087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor flush(); 130087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor pos = mPos; 131087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 132087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor System.arraycopy(buf, i, mText, pos, length); 133087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mPos = pos + length; 134087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 135087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 136087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private void append(String str) throws IOException { 137087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(str, 0, str.length()); 138087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 139087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 1408a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn private void appendIndent(int indent) throws IOException { 1418a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn indent *= 4; 1428a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn if (indent > sSpace.length()) { 1438a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn indent = sSpace.length(); 1448a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn } 1458a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn append(sSpace, 0, indent); 1468a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn } 1478a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn 148087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private void escapeAndAppendString(final String string) throws IOException { 149087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor final int N = string.length(); 150087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor final char NE = (char)ESCAPE_TABLE.length; 151087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor final String[] escapes = ESCAPE_TABLE; 152087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int lastPos = 0; 153087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int pos; 154087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor for (pos=0; pos<N; pos++) { 155087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor char c = string.charAt(pos); 156087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (c >= NE) continue; 157087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor String escape = escapes[c]; 158087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (escape == null) continue; 159087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (lastPos < pos) append(string, lastPos, pos-lastPos); 160087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor lastPos = pos + 1; 161087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(escape); 162087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 163087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (lastPos < pos) append(string, lastPos, pos-lastPos); 164087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 165087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 166087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private void escapeAndAppendString(char[] buf, int start, int len) throws IOException { 167087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor final char NE = (char)ESCAPE_TABLE.length; 168087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor final String[] escapes = ESCAPE_TABLE; 169087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int end = start+len; 170087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int lastPos = start; 171087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int pos; 172087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor for (pos=start; pos<end; pos++) { 173087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor char c = buf[pos]; 174087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (c >= NE) continue; 175087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor String escape = escapes[c]; 176087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (escape == null) continue; 177087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (lastPos < pos) append(buf, lastPos, pos-lastPos); 178087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor lastPos = pos + 1; 179087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(escape); 180087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 181087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (lastPos < pos) append(buf, lastPos, pos-lastPos); 182087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 183087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 184087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public XmlSerializer attribute(String namespace, String name, String value) throws IOException, 185087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalArgumentException, IllegalStateException { 186087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(' '); 187087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (namespace != null) { 188087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(namespace); 189087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(':'); 190087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 191087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(name); 192087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append("=\""); 193087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 194087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor escapeAndAppendString(value); 195087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append('"'); 1968a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mLineStart = false; 197087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return this; 198087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 199087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 200087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void cdsect(String text) throws IOException, IllegalArgumentException, 201087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 202087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 203087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 204087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 205087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void comment(String text) throws IOException, IllegalArgumentException, 206087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 207087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 208087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 209087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 210087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void docdecl(String text) throws IOException, IllegalArgumentException, 211087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 212087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 213087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 214087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 215087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void endDocument() throws IOException, IllegalArgumentException, IllegalStateException { 216087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor flush(); 217087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 218087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 219087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public XmlSerializer endTag(String namespace, String name) throws IOException, 220087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalArgumentException, IllegalStateException { 2218a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mNesting--; 222087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (mInTag) { 223087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(" />\n"); 224087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } else { 2258a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn if (mIndent && mLineStart) { 2268a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn appendIndent(mNesting); 2278a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn } 228087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append("</"); 229087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (namespace != null) { 230087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(namespace); 231087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(':'); 232087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 233087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(name); 234087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(">\n"); 235087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 2368a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mLineStart = true; 237087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mInTag = false; 238087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return this; 239087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 240087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 241087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void entityRef(String text) throws IOException, IllegalArgumentException, 242087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 243087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 244087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 245087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 246087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private void flushBytes() throws IOException { 247087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int position; 248087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if ((position = mBytes.position()) > 0) { 249087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mBytes.flip(); 250087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mOutputStream.write(mBytes.array(), 0, position); 251087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mBytes.clear(); 252087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 253087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 254087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 255087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void flush() throws IOException { 256087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor //Log.i("PackageManager", "flush mPos=" + mPos); 257087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (mPos > 0) { 258087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (mOutputStream != null) { 259087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor CharBuffer charBuffer = CharBuffer.wrap(mText, 0, mPos); 260087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor CoderResult result = mCharset.encode(charBuffer, mBytes, true); 261087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor while (true) { 262087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (result.isError()) { 263087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new IOException(result.toString()); 264087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } else if (result.isOverflow()) { 265087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor flushBytes(); 266087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor result = mCharset.encode(charBuffer, mBytes, true); 267087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor continue; 268087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 269087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor break; 270087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 271087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor flushBytes(); 272087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mOutputStream.flush(); 273087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } else { 274087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mWriter.write(mText, 0, mPos); 275087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mWriter.flush(); 276087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 277087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mPos = 0; 278087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 279087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 280087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 281087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public int getDepth() { 282087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 283087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 284087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 285087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public boolean getFeature(String name) { 286087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 287087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 288087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 289087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public String getName() { 290087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 291087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 292087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 293087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public String getNamespace() { 294087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 295087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 296087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 297087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public String getPrefix(String namespace, boolean generatePrefix) 298087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throws IllegalArgumentException { 299087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 300087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 301087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 302087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public Object getProperty(String name) { 303087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 304087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 305087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 306087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void ignorableWhitespace(String text) throws IOException, IllegalArgumentException, 307087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 308087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 309087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 310087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 311087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void processingInstruction(String text) throws IOException, IllegalArgumentException, 312087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 313087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 314087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 315087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 316087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void setFeature(String name, boolean state) throws IllegalArgumentException, 317087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 318087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (name.equals("http://xmlpull.org/v1/doc/features.html#indent-output")) { 3198a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mIndent = true; 320087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return; 321087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 322087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 323087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 324087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 325087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void setOutput(OutputStream os, String encoding) throws IOException, 326087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalArgumentException, IllegalStateException { 327087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (os == null) 328087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new IllegalArgumentException(); 329087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (true) { 330087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor try { 3313ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onuki mCharset = Charset.forName(encoding).newEncoder() 3323ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onuki .onMalformedInput(CodingErrorAction.REPLACE) 3333ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onuki .onUnmappableCharacter(CodingErrorAction.REPLACE); 334087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } catch (IllegalCharsetNameException e) { 335087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw (UnsupportedEncodingException) (new UnsupportedEncodingException( 336087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor encoding).initCause(e)); 337087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } catch (UnsupportedCharsetException e) { 338087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw (UnsupportedEncodingException) (new UnsupportedEncodingException( 339087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor encoding).initCause(e)); 340087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 341087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mOutputStream = os; 342087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } else { 343087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor setOutput( 344087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor encoding == null 345087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor ? new OutputStreamWriter(os) 346087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor : new OutputStreamWriter(os, encoding)); 347087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 348087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 349087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 350087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void setOutput(Writer writer) throws IOException, IllegalArgumentException, 351087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 352087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mWriter = writer; 353087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 354087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 355087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void setPrefix(String prefix, String namespace) throws IOException, 356087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalArgumentException, IllegalStateException { 357087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 358087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 359087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 360087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void setProperty(String name, Object value) throws IllegalArgumentException, 361087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 362087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 363087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 364087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 365087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void startDocument(String encoding, Boolean standalone) throws IOException, 366087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalArgumentException, IllegalStateException { 367087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append("<?xml version='1.0' encoding='utf-8' standalone='" 368087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor + (standalone ? "yes" : "no") + "' ?>\n"); 3698a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mLineStart = true; 370087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 371087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 372087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public XmlSerializer startTag(String namespace, String name) throws IOException, 373087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalArgumentException, IllegalStateException { 374087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (mInTag) { 375087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(">\n"); 376087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 3778a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn if (mIndent) { 3788a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn appendIndent(mNesting); 3798a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn } 3808a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mNesting++; 381087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append('<'); 382087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (namespace != null) { 383087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(namespace); 384087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(':'); 385087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 386087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(name); 387087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mInTag = true; 3888a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mLineStart = false; 389087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return this; 390087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 391087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 392087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public XmlSerializer text(char[] buf, int start, int len) throws IOException, 393087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalArgumentException, IllegalStateException { 394087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (mInTag) { 395087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(">"); 396087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mInTag = false; 397087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 398087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor escapeAndAppendString(buf, start, len); 3998a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn if (mIndent) { 4008a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mLineStart = buf[start+len-1] == '\n'; 4018a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn } 402087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return this; 403087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 404087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 405087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public XmlSerializer text(String text) throws IOException, IllegalArgumentException, 406087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 407087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (mInTag) { 408087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(">"); 409087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mInTag = false; 410087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 411087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor escapeAndAppendString(text); 4128a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn if (mIndent) { 4133029bf225cfa2c4b5b6e76303b0eba0d91c21026Jeff Sharkey mLineStart = text.length() > 0 && (text.charAt(text.length()-1) == '\n'); 4148a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn } 415087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return this; 416087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 417087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 418087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor} 419