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 52087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private static final int BUFFER_LEN = 8192; 53087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 548a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn private static String sSpace = " "; 558a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn 56087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private final char[] mText = new char[BUFFER_LEN]; 57087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private int mPos; 58087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 59087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private Writer mWriter; 60087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 61087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private OutputStream mOutputStream; 62087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private CharsetEncoder mCharset; 63087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private ByteBuffer mBytes = ByteBuffer.allocate(BUFFER_LEN); 64087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 658a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn private boolean mIndent = false; 66087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private boolean mInTag; 67087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 688a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn private int mNesting = 0; 698a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn private boolean mLineStart = true; 708a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn 71087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private void append(char c) throws IOException { 72087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int pos = mPos; 73087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (pos >= (BUFFER_LEN-1)) { 74087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor flush(); 75087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor pos = mPos; 76087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 77087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mText[pos] = c; 78087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mPos = pos+1; 79087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 80087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 81087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private void append(String str, int i, final int length) throws IOException { 82087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (length > BUFFER_LEN) { 83087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor final int end = i + length; 84087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor while (i < end) { 85087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int next = i + BUFFER_LEN; 86087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(str, i, next<end ? BUFFER_LEN : (end-i)); 87087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor i = next; 88087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 89087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return; 90087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 91087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int pos = mPos; 92087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if ((pos+length) > BUFFER_LEN) { 93087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor flush(); 94087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor pos = mPos; 95087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 96087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor str.getChars(i, i+length, mText, pos); 97087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mPos = pos + length; 98087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 99087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 100087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private void append(char[] buf, int i, final int length) throws IOException { 101087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (length > BUFFER_LEN) { 102087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor final int end = i + length; 103087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor while (i < end) { 104087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int next = i + BUFFER_LEN; 105087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(buf, i, next<end ? BUFFER_LEN : (end-i)); 106087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor i = next; 107087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 108087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return; 109087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 110087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int pos = mPos; 111087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if ((pos+length) > BUFFER_LEN) { 112087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor flush(); 113087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor pos = mPos; 114087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 115087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor System.arraycopy(buf, i, mText, pos, length); 116087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mPos = pos + length; 117087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 118087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 119087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private void append(String str) throws IOException { 120087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(str, 0, str.length()); 121087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 122087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 1238a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn private void appendIndent(int indent) throws IOException { 1248a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn indent *= 4; 1258a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn if (indent > sSpace.length()) { 1268a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn indent = sSpace.length(); 1278a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn } 1288a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn append(sSpace, 0, indent); 1298a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn } 1308a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn 131087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private void escapeAndAppendString(final String string) throws IOException { 132087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor final int N = string.length(); 133087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor final char NE = (char)ESCAPE_TABLE.length; 134087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor final String[] escapes = ESCAPE_TABLE; 135087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int lastPos = 0; 136087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int pos; 137087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor for (pos=0; pos<N; pos++) { 138087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor char c = string.charAt(pos); 139087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (c >= NE) continue; 140087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor String escape = escapes[c]; 141087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (escape == null) continue; 142087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (lastPos < pos) append(string, lastPos, pos-lastPos); 143087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor lastPos = pos + 1; 144087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(escape); 145087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 146087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (lastPos < pos) append(string, lastPos, pos-lastPos); 147087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 148087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 149087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private void escapeAndAppendString(char[] buf, int start, int len) throws IOException { 150087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor final char NE = (char)ESCAPE_TABLE.length; 151087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor final String[] escapes = ESCAPE_TABLE; 152087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int end = start+len; 153087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int lastPos = start; 154087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int pos; 155087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor for (pos=start; pos<end; pos++) { 156087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor char c = buf[pos]; 157087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (c >= NE) continue; 158087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor String escape = escapes[c]; 159087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (escape == null) continue; 160087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (lastPos < pos) append(buf, lastPos, pos-lastPos); 161087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor lastPos = pos + 1; 162087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(escape); 163087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 164087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (lastPos < pos) append(buf, lastPos, pos-lastPos); 165087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 166087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 167087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public XmlSerializer attribute(String namespace, String name, String value) throws IOException, 168087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalArgumentException, IllegalStateException { 169087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(' '); 170087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (namespace != null) { 171087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(namespace); 172087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(':'); 173087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 174087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(name); 175087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append("=\""); 176087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 177087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor escapeAndAppendString(value); 178087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append('"'); 1798a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mLineStart = false; 180087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return this; 181087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 182087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 183087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void cdsect(String text) throws IOException, IllegalArgumentException, 184087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 185087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 186087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 187087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 188087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void comment(String text) throws IOException, IllegalArgumentException, 189087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 190087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 191087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 192087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 193087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void docdecl(String text) throws IOException, IllegalArgumentException, 194087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 195087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 196087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 197087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 198087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void endDocument() throws IOException, IllegalArgumentException, IllegalStateException { 199087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor flush(); 200087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 201087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 202087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public XmlSerializer endTag(String namespace, String name) throws IOException, 203087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalArgumentException, IllegalStateException { 2048a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mNesting--; 205087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (mInTag) { 206087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(" />\n"); 207087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } else { 2088a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn if (mIndent && mLineStart) { 2098a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn appendIndent(mNesting); 2108a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn } 211087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append("</"); 212087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (namespace != null) { 213087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(namespace); 214087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(':'); 215087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 216087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(name); 217087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(">\n"); 218087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 2198a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mLineStart = true; 220087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mInTag = false; 221087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return this; 222087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 223087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 224087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void entityRef(String text) throws IOException, IllegalArgumentException, 225087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 226087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 227087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 228087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 229087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor private void flushBytes() throws IOException { 230087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor int position; 231087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if ((position = mBytes.position()) > 0) { 232087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mBytes.flip(); 233087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mOutputStream.write(mBytes.array(), 0, position); 234087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mBytes.clear(); 235087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 236087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 237087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 238087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void flush() throws IOException { 239087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor //Log.i("PackageManager", "flush mPos=" + mPos); 240087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (mPos > 0) { 241087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (mOutputStream != null) { 242087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor CharBuffer charBuffer = CharBuffer.wrap(mText, 0, mPos); 243087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor CoderResult result = mCharset.encode(charBuffer, mBytes, true); 244087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor while (true) { 245087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (result.isError()) { 246087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new IOException(result.toString()); 247087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } else if (result.isOverflow()) { 248087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor flushBytes(); 249087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor result = mCharset.encode(charBuffer, mBytes, true); 250087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor continue; 251087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 252087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor break; 253087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 254087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor flushBytes(); 255087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mOutputStream.flush(); 256087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } else { 257087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mWriter.write(mText, 0, mPos); 258087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mWriter.flush(); 259087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 260087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mPos = 0; 261087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 262087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 263087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 264087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public int getDepth() { 265087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 266087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 267087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 268087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public boolean getFeature(String name) { 269087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 270087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 271087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 272087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public String getName() { 273087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 274087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 275087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 276087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public String getNamespace() { 277087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 278087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 279087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 280087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public String getPrefix(String namespace, boolean generatePrefix) 281087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throws IllegalArgumentException { 282087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 283087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 284087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 285087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public Object getProperty(String name) { 286087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 287087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 288087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 289087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void ignorableWhitespace(String text) throws IOException, IllegalArgumentException, 290087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 291087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 292087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 293087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 294087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void processingInstruction(String text) throws IOException, IllegalArgumentException, 295087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 296087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 297087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 298087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 299087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void setFeature(String name, boolean state) throws IllegalArgumentException, 300087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 301087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (name.equals("http://xmlpull.org/v1/doc/features.html#indent-output")) { 3028a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mIndent = true; 303087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return; 304087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 305087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 306087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 307087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 308087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void setOutput(OutputStream os, String encoding) throws IOException, 309087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalArgumentException, IllegalStateException { 310087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (os == null) 311087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new IllegalArgumentException(); 312087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (true) { 313087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor try { 3143ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onuki mCharset = Charset.forName(encoding).newEncoder() 3153ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onuki .onMalformedInput(CodingErrorAction.REPLACE) 3163ae3557ea3a9ad8429de9db14de62a4214a07cdcMakoto Onuki .onUnmappableCharacter(CodingErrorAction.REPLACE); 317087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } catch (IllegalCharsetNameException e) { 318087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw (UnsupportedEncodingException) (new UnsupportedEncodingException( 319087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor encoding).initCause(e)); 320087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } catch (UnsupportedCharsetException e) { 321087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw (UnsupportedEncodingException) (new UnsupportedEncodingException( 322087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor encoding).initCause(e)); 323087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 324087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mOutputStream = os; 325087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } else { 326087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor setOutput( 327087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor encoding == null 328087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor ? new OutputStreamWriter(os) 329087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor : new OutputStreamWriter(os, encoding)); 330087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 331087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 332087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 333087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void setOutput(Writer writer) throws IOException, IllegalArgumentException, 334087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 335087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mWriter = writer; 336087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 337087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 338087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void setPrefix(String prefix, String namespace) throws IOException, 339087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalArgumentException, IllegalStateException { 340087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 341087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 342087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 343087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void setProperty(String name, Object value) throws IllegalArgumentException, 344087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 345087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor throw new UnsupportedOperationException(); 346087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 347087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 348087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public void startDocument(String encoding, Boolean standalone) throws IOException, 349087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalArgumentException, IllegalStateException { 350087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append("<?xml version='1.0' encoding='utf-8' standalone='" 351087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor + (standalone ? "yes" : "no") + "' ?>\n"); 3528a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mLineStart = true; 353087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 354087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 355087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public XmlSerializer startTag(String namespace, String name) throws IOException, 356087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalArgumentException, IllegalStateException { 357087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (mInTag) { 358087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(">\n"); 359087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 3608a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn if (mIndent) { 3618a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn appendIndent(mNesting); 3628a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn } 3638a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mNesting++; 364087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append('<'); 365087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (namespace != null) { 366087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(namespace); 367087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(':'); 368087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 369087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(name); 370087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mInTag = true; 3718a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mLineStart = false; 372087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return this; 373087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 374087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 375087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public XmlSerializer text(char[] buf, int start, int len) throws IOException, 376087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalArgumentException, IllegalStateException { 377087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (mInTag) { 378087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(">"); 379087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mInTag = false; 380087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 381087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor escapeAndAppendString(buf, start, len); 3828a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn if (mIndent) { 3838a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn mLineStart = buf[start+len-1] == '\n'; 3848a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn } 385087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return this; 386087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 387087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 388087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor public XmlSerializer text(String text) throws IOException, IllegalArgumentException, 389087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor IllegalStateException { 390087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor if (mInTag) { 391087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor append(">"); 392087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor mInTag = false; 393087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 394087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor escapeAndAppendString(text); 3958a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn if (mIndent) { 3963029bf225cfa2c4b5b6e76303b0eba0d91c21026Jeff Sharkey mLineStart = text.length() > 0 && (text.charAt(text.length()-1) == '\n'); 3978a2ed1d7c0c4f6476e39cc37d9ebd29c7562ce01Dianne Hackborn } 398087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor return this; 399087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor } 400087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor 401087ff0b93580760bf0c5dd36a0081289224b1cdeTom Taylor} 402