1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a copy
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of this software and associated documentation files (the "Software"), to deal
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in the Software without restriction, including without limitation the rights
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to use, copy, modify, merge, publish, distribute, sublicense, and/or
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * sell copies of the Software, and to permit persons to whom the Software is
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * furnished to do so, subject to the following conditions:
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The  above copyright notice and this permission notice shall be included in
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * all copies or substantial portions of the Software.
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * IN THE SOFTWARE. */
20f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage org.kxml2.io;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.*;
2578e3320540c8bdcbefba5ae1222ee18f6679ab33Elliott Hughesimport java.util.Locale;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xmlpull.v1.*;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class KXmlSerializer implements XmlSerializer {
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
30c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz    private static final int BUFFER_LEN = 8192;
31c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz    private final char[] mText = new char[BUFFER_LEN];
32c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz    private int mPos;
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
34c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz    //    static final String UNDEFINED = ":";
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
36c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz    private Writer writer;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean pending;
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int auto;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int depth;
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String[] elementStack = new String[12];
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //nsp/prefix/name
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int[] nspCounts = new int[4];
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String[] nspStack = new String[8];
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //prefix/nsp; both empty are ""
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean[] indent = new boolean[4];
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean unicode;
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String encoding;
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
51c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz    private void append(char c) throws IOException {
52c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        if (mPos >= BUFFER_LEN) {
53c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            flushBuffer();
54c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        }
55c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        mText[mPos++] = c;
56c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz    }
57c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz
58c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz    private void append(String str, int i, int length) throws IOException {
59c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        while (length > 0) {
60c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            if (mPos == BUFFER_LEN) {
61c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                flushBuffer();
62c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            }
63c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            int batch = BUFFER_LEN - mPos;
64c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            if (batch > length) {
65c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                batch = length;
66c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            }
67c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            str.getChars(i, i + batch, mText, mPos);
68c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            i += batch;
69c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            length -= batch;
70c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            mPos += batch;
71c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        }
72c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz    }
73c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz
74c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz    private void append(String str) throws IOException {
75c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append(str, 0, str.length());
76c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz    }
77c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz
78c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz    private final void flushBuffer() throws IOException {
79c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        if(mPos > 0) {
80c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            writer.write(mText, 0, mPos);
81c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            writer.flush();
82c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            mPos = 0;
83c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        }
84c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz    }
85c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final void check(boolean close) throws IOException {
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!pending)
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        depth++;
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pending = false;
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (indent.length <= depth) {
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            boolean[] hlp = new boolean[depth + 4];
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(indent, 0, hlp, 0, depth);
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            indent = hlp;
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        indent[depth] = indent[depth - 1];
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
10080a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes        for (int i = nspCounts[depth - 1]; i < nspCounts[depth]; i++) {
101c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append(" xmlns");
10280a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            if (!nspStack[i * 2].isEmpty()) {
103c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                append(':');
104c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                append(nspStack[i * 2]);
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
10680a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            else if (getNamespace().isEmpty() && !nspStack[i * 2 + 1].isEmpty())
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
108c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append("=\"");
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writeEscaped(nspStack[i * 2 + 1], '"');
110c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append('"');
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (nspCounts.length <= depth + 1) {
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int[] hlp = new int[depth + 8];
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(nspCounts, 0, hlp, 0, depth + 1);
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            nspCounts = hlp;
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspCounts[depth + 1] = nspCounts[depth];
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //   nspCounts[depth + 2] = nspCounts[depth];
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
122c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        if (close) {
123c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append(" />");
124c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        } else {
125c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append('>');
126c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        }
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
129866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes    private final void writeEscaped(String s, int quot) throws IOException {
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = 0; i < s.length(); i++) {
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            char c = s.charAt(i);
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            switch (c) {
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case '\n':
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case '\r':
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case '\t':
136f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                    if(quot == -1)
137c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                        append(c);
138f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                    else
139c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                        append("&#"+((int) c)+';');
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case '&' :
142c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                    append("&amp;");
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case '>' :
145c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                    append("&gt;");
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case '<' :
148c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                    append("&lt;");
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
150866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes                default:
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (c == quot) {
152c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                        append(c == '"' ? "&quot;" : "&apos;");
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        break;
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1555d175dd4d7b128492ef7e3da6a77d80b8fd0aa22Tobias Thierer                    // BEGIN Android-changed: refuse to output invalid characters
156ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    // See http://www.w3.org/TR/REC-xml/#charsets for definition.
157ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    // No other Java XML writer we know of does this, but no Java
158ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    // XML reader we know of is able to parse the bad output we'd
159ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    // otherwise generate.
160ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    // Note: tab, newline, and carriage return have already been
161ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    // handled above.
1623f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes                    boolean allowedInXml = (c >= 0x20 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xfffd);
1633f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes                    if (allowedInXml) {
1643f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes                        if (unicode || c < 127) {
165c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                            append(c);
1663f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes                        } else {
167c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                            append("&#" + ((int) c) + ";");
1683f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes                        }
1693f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes                    } else if (Character.isHighSurrogate(c) && i < s.length() - 1) {
1703f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes                        writeSurrogate(c, s.charAt(i + 1));
1713f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes                        ++i;
172ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    } else {
1733f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes                        reportInvalidCharacter(c);
174ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    }
1755d175dd4d7b128492ef7e3da6a77d80b8fd0aa22Tobias Thierer                    // END Android-changed
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1805d175dd4d7b128492ef7e3da6a77d80b8fd0aa22Tobias Thierer    // BEGIN Android-added
181ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes    private static void reportInvalidCharacter(char ch) {
1823f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes        throw new IllegalArgumentException("Illegal character (U+" + Integer.toHexString((int) ch) + ")");
183ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes    }
1845d175dd4d7b128492ef7e3da6a77d80b8fd0aa22Tobias Thierer    // END Android-added
185ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final void writeIndent() throws IOException {
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write("\r\n");
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i < depth; i++)
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                writer.write(' ');
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }*/
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void docdecl(String dd) throws IOException {
194c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append("<!DOCTYPE");
195c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append(dd);
196c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append('>');
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void endDocument() throws IOException {
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (depth > 0) {
201866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes            endTag(elementStack[depth * 3 - 3], elementStack[depth * 3 - 1]);
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        flush();
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void entityRef(String name) throws IOException {
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
208c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append('&');
209c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append(name);
210c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append(';');
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getFeature(String name) {
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //return false;
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            "http://xmlpull.org/v1/doc/features.html#indent-output"
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                .equals(
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                name))
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ? indent[depth]
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            : false;
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getPrefix(String namespace, boolean create) {
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return getPrefix(namespace, false, create);
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        catch (IOException e) {
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new RuntimeException(e.toString());
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final String getPrefix(
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String namespace,
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean includeDefault,
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean create)
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = nspCounts[depth + 1] * 2 - 2;
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            i >= 0;
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            i -= 2) {
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (nspStack[i + 1].equals(namespace)
24280a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes                && (includeDefault || !nspStack[i].isEmpty())) {
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String cand = nspStack[i];
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int j = i + 2;
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    j < nspCounts[depth + 1] * 2;
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    j++) {
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (nspStack[j].equals(cand)) {
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        cand = null;
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        break;
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (cand != null)
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return cand;
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!create)
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String prefix;
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
26280a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes        if (namespace.isEmpty())
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            prefix = "";
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        else {
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            do {
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                prefix = "n" + (auto++);
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = nspCounts[depth + 1] * 2 - 2;
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    i >= 0;
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    i -= 2) {
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (prefix.equals(nspStack[i])) {
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        prefix = null;
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        break;
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (prefix == null);
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean p = pending;
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pending = false;
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        setPrefix(prefix, namespace);
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pending = p;
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return prefix;
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Object getProperty(String name) {
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throw new RuntimeException("Unsupported property");
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void ignorableWhitespace(String s)
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        text(s);
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setFeature(String name, boolean value) {
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ("http://xmlpull.org/v1/doc/features.html#indent-output"
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            .equals(name)) {
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            indent[depth] = value;
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        else
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new RuntimeException("Unsupported Feature");
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setProperty(String name, Object value) {
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throw new RuntimeException(
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            "Unsupported Property:" + value);
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setPrefix(String prefix, String namespace)
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (prefix == null)
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            prefix = "";
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (namespace == null)
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            namespace = "";
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String defined = getPrefix(namespace, true, false);
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // boil out if already defined
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (prefix.equals(defined))
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int pos = (nspCounts[depth + 1]++) << 1;
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (nspStack.length < pos + 1) {
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String[] hlp = new String[nspStack.length + 16];
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(nspStack, 0, hlp, 0, pos);
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            nspStack = hlp;
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspStack[pos++] = prefix;
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspStack[pos] = namespace;
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setOutput(Writer writer) {
338c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        this.writer = writer;
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // elementStack = new String[12]; //nsp/prefix/name
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //nspCounts = new int[4];
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //nspStack = new String[8]; //prefix/nsp
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //indent = new boolean[4];
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspCounts[0] = 2;
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspCounts[1] = 2;
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspStack[0] = "";
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspStack[1] = "";
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspStack[2] = "xml";
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspStack[3] = "http://www.w3.org/XML/1998/namespace";
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pending = false;
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        auto = 0;
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        depth = 0;
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        unicode = false;
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setOutput(OutputStream os, String encoding)
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (os == null)
361cff1616012dc0d56c2da9af2b9b1183e76c7e044Elliott Hughes            throw new IllegalArgumentException("os == null");
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        setOutput(
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            encoding == null
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ? new OutputStreamWriter(os)
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                : new OutputStreamWriter(os, encoding));
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.encoding = encoding;
36778e3320540c8bdcbefba5ae1222ee18f6679ab33Elliott Hughes        if (encoding != null && encoding.toLowerCase(Locale.US).startsWith("utf")) {
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            unicode = true;
36978e3320540c8bdcbefba5ae1222ee18f6679ab33Elliott Hughes        }
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
37278e3320540c8bdcbefba5ae1222ee18f6679ab33Elliott Hughes    public void startDocument(String encoding, Boolean standalone) throws IOException {
373c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append("<?xml version='1.0' ");
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (encoding != null) {
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.encoding = encoding;
37778e3320540c8bdcbefba5ae1222ee18f6679ab33Elliott Hughes            if (encoding.toLowerCase(Locale.US).startsWith("utf")) {
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                unicode = true;
37978e3320540c8bdcbefba5ae1222ee18f6679ab33Elliott Hughes            }
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.encoding != null) {
383c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append("encoding='");
384c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append(this.encoding);
385c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append("' ");
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (standalone != null) {
389c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append("standalone='");
390c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append(standalone.booleanValue() ? "yes" : "no");
391c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append("' ");
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
393c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append("?>");
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public XmlSerializer startTag(String namespace, String name)
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //        if (namespace == null)
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //            namespace = "";
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (indent[depth]) {
404c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append("\r\n");
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i < depth; i++)
406c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                append("  ");
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int esp = depth * 3;
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (elementStack.length < esp + 3) {
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String[] hlp = new String[elementStack.length + 12];
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(elementStack, 0, hlp, 0, esp);
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            elementStack = hlp;
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String prefix =
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            namespace == null
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ? ""
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                : getPrefix(namespace, true, true);
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
422b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (namespace != null && namespace.isEmpty()) {
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = nspCounts[depth];
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                i < nspCounts[depth + 1];
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                i++) {
42680a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes                if (nspStack[i * 2].isEmpty() && !nspStack[i * 2 + 1].isEmpty()) {
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        elementStack[esp++] = namespace;
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        elementStack[esp++] = prefix;
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        elementStack[esp] = name;
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
436c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append('<');
43780a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes        if (!prefix.isEmpty()) {
438c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append(prefix);
439c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append(':');
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
442c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append(name);
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pending = true;
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return this;
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public XmlSerializer attribute(
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String namespace,
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String name,
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String value)
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!pending)
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalStateException("illegal position for attribute");
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //        int cnt = nspCounts[depth];
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (namespace == null)
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            namespace = "";
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //        depth--;
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //        pending = false;
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String prefix =
46680a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            namespace.isEmpty()
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ? ""
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                : getPrefix(namespace, false, true);
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //        pending = true;
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //        depth++;
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /*        if (cnt != nspCounts[depth]) {
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    writer.write(' ');
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    writer.write("xmlns");
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (nspStack[cnt * 2] != null) {
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        writer.write(':');
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        writer.write(nspStack[cnt * 2]);
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    writer.write("=\"");
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    writeEscaped(nspStack[cnt * 2 + 1], '"');
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    writer.write('"');
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                */
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
486c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append(' ');
48780a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes        if (!prefix.isEmpty()) {
488c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append(prefix);
489c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append(':');
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
491c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append(name);
492c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append('=');
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        char q = value.indexOf('"') == -1 ? '"' : '\'';
494c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append(q);
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writeEscaped(value, q);
496c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append(q);
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return this;
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void flush() throws IOException {
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
503c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        flushBuffer();
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void close() throws IOException {
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            check();
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.close();
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    */
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public XmlSerializer endTag(String namespace, String name)
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!pending)
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            depth--;
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //        if (namespace == null)
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //          namespace = "";
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((namespace == null
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            && elementStack[depth * 3] != null)
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            || (namespace != null
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && !namespace.equals(elementStack[depth * 3]))
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            || !elementStack[depth * 3 + 2].equals(name))
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException("</{"+namespace+"}"+name+"> does not match start");
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (pending) {
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            check(true);
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            depth--;
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        else {
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (indent[depth + 1]) {
532c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                append("\r\n");
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 0; i < depth; i++)
534c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                    append("  ");
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
537c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append("</");
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String prefix = elementStack[depth * 3 + 1];
53980a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            if (!prefix.isEmpty()) {
540c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                append(prefix);
541c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                append(':');
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
543c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append(name);
544c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz            append('>');
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspCounts[depth + 1] = nspCounts[depth];
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return this;
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getNamespace() {
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 3];
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getName() {
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 1];
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getDepth() {
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return pending ? depth + 1 : depth;
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public XmlSerializer text(String text) throws IOException {
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        indent[depth] = false;
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writeEscaped(text, -1);
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return this;
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public XmlSerializer text(char[] text, int start, int len)
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        text(new String(text, start, len));
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return this;
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void cdsect(String data) throws IOException {
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
5785d175dd4d7b128492ef7e3da6a77d80b8fd0aa22Tobias Thierer        // BEGIN Android-changed: ]]> is not allowed within a CDATA,
579ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes        // so break and start a new one when necessary.
580ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes        data = data.replace("]]>", "]]]]><![CDATA[>");
581c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append("<![CDATA[");
5823f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes        for (int i = 0; i < data.length(); ++i) {
5833f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes            char ch = data.charAt(i);
5843f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes            boolean allowedInCdata = (ch >= 0x20 && ch <= 0xd7ff) ||
585ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    (ch == '\t' || ch == '\n' || ch == '\r') ||
586ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    (ch >= 0xe000 && ch <= 0xfffd);
5873f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes            if (allowedInCdata) {
588c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                append(ch);
5893f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes            } else if (Character.isHighSurrogate(ch) && i < data.length() - 1) {
5903f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes                // Character entities aren't valid in CDATA, so break out for this.
591c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                append("]]>");
5923f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes                writeSurrogate(ch, data.charAt(++i));
593c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz                append("<![CDATA[");
5943f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes            } else {
595ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                reportInvalidCharacter(ch);
596ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes            }
597ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes        }
598c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append("]]>");
5995d175dd4d7b128492ef7e3da6a77d80b8fd0aa22Tobias Thierer        // END Android-changed
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
6025d175dd4d7b128492ef7e3da6a77d80b8fd0aa22Tobias Thierer    // BEGIN Android-added
6033f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes    private void writeSurrogate(char high, char low) throws IOException {
6043f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes        if (!Character.isLowSurrogate(low)) {
6053f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes            throw new IllegalArgumentException("Bad surrogate pair (U+" + Integer.toHexString((int) high) +
6063f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes                                               " U+" + Integer.toHexString((int) low) + ")");
6073f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes        }
6083f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes        // Java-style surrogate pairs aren't allowed in XML. We could use the > 3-byte encodings, but that
6093f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes        // seems likely to upset anything expecting modified UTF-8 rather than "real" UTF-8. It seems more
6103f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes        // conservative in a Java environment to use an entity reference instead.
6113f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes        int codePoint = Character.toCodePoint(high, low);
612c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append("&#" + codePoint + ";");
6133f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes    }
6145d175dd4d7b128492ef7e3da6a77d80b8fd0aa22Tobias Thierer    // END Android-added
6153f1a5ebc337e896977bbc75aa2dc370e97805794Elliott Hughes
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void comment(String comment) throws IOException {
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
618c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append("<!--");
619c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append(comment);
620c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append("-->");
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void processingInstruction(String pi)
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
626c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append("<?");
627c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append(pi);
628c3dc3f7b4d1abfc9d52f87ed47921c53942f9a86Wojciech Staszkiewicz        append("?>");
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
631