KXmlSerializer.java revision f33eae7e84eb6d3b0f4e86b59605bb3de73009f3
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.*;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xmlpull.v1.*;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class KXmlSerializer implements XmlSerializer {
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //    static final String UNDEFINED = ":";
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // BEGIN android-added
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /** size (in characters) for the write buffer */
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final int WRITE_BUFFER_SIZE = 500;
34f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    // END android-added
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // BEGIN android-changed
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // (Guarantee that the writer is always buffered.)
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private BufferedWriter writer;
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // END android-changed
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean pending;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int auto;
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int depth;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String[] elementStack = new String[12];
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //nsp/prefix/name
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int[] nspCounts = new int[4];
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String[] nspStack = new String[8];
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //prefix/nsp; both empty are ""
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean[] indent = new boolean[4];
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean unicode;
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String encoding;
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final void check(boolean close) throws IOException {
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!pending)
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        depth++;
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pending = false;
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (indent.length <= depth) {
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            boolean[] hlp = new boolean[depth + 4];
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(indent, 0, hlp, 0, depth);
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            indent = hlp;
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        indent[depth] = indent[depth - 1];
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = nspCounts[depth - 1];
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            i < nspCounts[depth];
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            i++) {
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write(' ');
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write("xmlns");
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!"".equals(nspStack[i * 2])) {
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                writer.write(':');
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                writer.write(nspStack[i * 2]);
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            else if ("".equals(getNamespace()) && !"".equals(nspStack[i * 2 + 1]))
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write("=\"");
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writeEscaped(nspStack[i * 2 + 1], '"');
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write('"');
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (nspCounts.length <= depth + 1) {
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int[] hlp = new int[depth + 8];
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(nspCounts, 0, hlp, 0, depth + 1);
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            nspCounts = hlp;
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspCounts[depth + 1] = nspCounts[depth];
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //   nspCounts[depth + 2] = nspCounts[depth];
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write(close ? " />" : ">");
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final void writeEscaped(String s, int quot)
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = 0; i < s.length(); i++) {
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            char c = s.charAt(i);
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            switch (c) {
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case '\n':
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case '\r':
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case '\t':
105f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                    if(quot == -1)
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        writer.write(c);
107f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                    else
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        writer.write("&#"+((int) c)+';');
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case '&' :
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    writer.write("&amp;");
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case '>' :
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    writer.write("&gt;");
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case '<' :
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    writer.write("&lt;");
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case '"' :
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case '\'' :
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (c == quot) {
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        writer.write(
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            c == '"' ? "&quot;" : "&apos;");
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        break;
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                default :
127ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    // BEGIN android-changed: refuse to output invalid characters
128ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    // See http://www.w3.org/TR/REC-xml/#charsets for definition.
129ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    // No other Java XML writer we know of does this, but no Java
130ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    // XML reader we know of is able to parse the bad output we'd
131ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    // otherwise generate.
132ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    // Note: tab, newline, and carriage return have already been
133ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    // handled above.
134ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    boolean valid = (c >= 0x20 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xfffd);
135ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    if (!valid) {
136ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                        reportInvalidCharacter(c);
137ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    }
138ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    if (unicode || c < 127) {
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        writer.write(c);
140ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    } else {
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        writer.write("&#" + ((int) c) + ";");
142ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    }
143ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    // END android-changed
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
148ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes    // BEGIN android-added
149ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes    private static void reportInvalidCharacter(char ch) {
150ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes        throw new IllegalArgumentException("Illegal character (" + Integer.toHexString((int) ch) + ")");
151ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes    }
152ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes    // END android-added
153ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final void writeIndent() throws IOException {
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write("\r\n");
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i < depth; i++)
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                writer.write(' ');
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }*/
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void docdecl(String dd) throws IOException {
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write("<!DOCTYPE");
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write(dd);
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write(">");
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void endDocument() throws IOException {
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (depth > 0) {
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            endTag(
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                elementStack[depth * 3 - 3],
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                elementStack[depth * 3 - 1]);
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        flush();
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void entityRef(String name) throws IOException {
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write('&');
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write(name);
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write(';');
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getFeature(String name) {
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //return false;
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            "http://xmlpull.org/v1/doc/features.html#indent-output"
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                .equals(
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                name))
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ? indent[depth]
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            : false;
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getPrefix(String namespace, boolean create) {
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return getPrefix(namespace, false, create);
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        catch (IOException e) {
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new RuntimeException(e.toString());
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final String getPrefix(
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String namespace,
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean includeDefault,
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean create)
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = nspCounts[depth + 1] * 2 - 2;
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            i >= 0;
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            i -= 2) {
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (nspStack[i + 1].equals(namespace)
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && (includeDefault || !nspStack[i].equals(""))) {
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String cand = nspStack[i];
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int j = i + 2;
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    j < nspCounts[depth + 1] * 2;
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    j++) {
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (nspStack[j].equals(cand)) {
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        cand = null;
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        break;
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (cand != null)
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return cand;
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!create)
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String prefix;
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ("".equals(namespace))
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            prefix = "";
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        else {
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            do {
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                prefix = "n" + (auto++);
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = nspCounts[depth + 1] * 2 - 2;
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    i >= 0;
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    i -= 2) {
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (prefix.equals(nspStack[i])) {
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        prefix = null;
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        break;
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (prefix == null);
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean p = pending;
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pending = false;
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        setPrefix(prefix, namespace);
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pending = p;
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return prefix;
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Object getProperty(String name) {
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throw new RuntimeException("Unsupported property");
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void ignorableWhitespace(String s)
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        text(s);
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setFeature(String name, boolean value) {
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ("http://xmlpull.org/v1/doc/features.html#indent-output"
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            .equals(name)) {
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            indent[depth] = value;
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        else
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new RuntimeException("Unsupported Feature");
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setProperty(String name, Object value) {
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throw new RuntimeException(
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            "Unsupported Property:" + value);
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setPrefix(String prefix, String namespace)
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (prefix == null)
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            prefix = "";
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (namespace == null)
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            namespace = "";
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String defined = getPrefix(namespace, true, false);
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // boil out if already defined
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (prefix.equals(defined))
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int pos = (nspCounts[depth + 1]++) << 1;
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (nspStack.length < pos + 1) {
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String[] hlp = new String[nspStack.length + 16];
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(nspStack, 0, hlp, 0, pos);
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            nspStack = hlp;
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspStack[pos++] = prefix;
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspStack[pos] = namespace;
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setOutput(Writer writer) {
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // BEGIN android-changed
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Guarantee that the writer is always buffered.
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (writer instanceof BufferedWriter) {
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.writer = (BufferedWriter) writer;
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.writer = new BufferedWriter(writer, WRITE_BUFFER_SIZE);
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // END android-changed
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // elementStack = new String[12]; //nsp/prefix/name
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //nspCounts = new int[4];
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //nspStack = new String[8]; //prefix/nsp
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //indent = new boolean[4];
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspCounts[0] = 2;
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspCounts[1] = 2;
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspStack[0] = "";
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspStack[1] = "";
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspStack[2] = "xml";
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspStack[3] = "http://www.w3.org/XML/1998/namespace";
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pending = false;
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        auto = 0;
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        depth = 0;
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        unicode = false;
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setOutput(OutputStream os, String encoding)
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (os == null)
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException();
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        setOutput(
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            encoding == null
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ? new OutputStreamWriter(os)
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                : new OutputStreamWriter(os, encoding));
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.encoding = encoding;
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (encoding != null
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            && encoding.toLowerCase().startsWith("utf"))
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            unicode = true;
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void startDocument(
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String encoding,
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Boolean standalone)
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write("<?xml version='1.0' ");
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (encoding != null) {
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.encoding = encoding;
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (encoding.toLowerCase().startsWith("utf"))
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                unicode = true;
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.encoding != null) {
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write("encoding='");
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write(this.encoding);
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write("' ");
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (standalone != null) {
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write("standalone='");
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write(
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                standalone.booleanValue() ? "yes" : "no");
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write("' ");
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write("?>");
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public XmlSerializer startTag(String namespace, String name)
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //        if (namespace == null)
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //            namespace = "";
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (indent[depth]) {
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write("\r\n");
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i < depth; i++)
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                writer.write("  ");
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int esp = depth * 3;
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (elementStack.length < esp + 3) {
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String[] hlp = new String[elementStack.length + 12];
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(elementStack, 0, hlp, 0, esp);
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            elementStack = hlp;
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String prefix =
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            namespace == null
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ? ""
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                : getPrefix(namespace, true, true);
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ("".equals(namespace)) {
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = nspCounts[depth];
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                i < nspCounts[depth + 1];
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                i++) {
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if ("".equals(nspStack[i * 2]) && !"".equals(nspStack[i * 2 + 1])) {
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        elementStack[esp++] = namespace;
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        elementStack[esp++] = prefix;
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        elementStack[esp] = name;
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write('<');
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!"".equals(prefix)) {
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write(prefix);
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write(':');
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write(name);
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pending = true;
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return this;
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public XmlSerializer attribute(
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String namespace,
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String name,
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String value)
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!pending)
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalStateException("illegal position for attribute");
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //        int cnt = nspCounts[depth];
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (namespace == null)
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            namespace = "";
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //        depth--;
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //        pending = false;
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String prefix =
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            "".equals(namespace)
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ? ""
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                : getPrefix(namespace, false, true);
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //        pending = true;
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //        depth++;
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /*        if (cnt != nspCounts[depth]) {
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    writer.write(' ');
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    writer.write("xmlns");
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (nspStack[cnt * 2] != null) {
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        writer.write(':');
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        writer.write(nspStack[cnt * 2]);
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    writer.write("=\"");
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    writeEscaped(nspStack[cnt * 2 + 1], '"');
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    writer.write('"');
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                */
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write(' ');
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!"".equals(prefix)) {
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write(prefix);
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write(':');
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write(name);
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write('=');
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        char q = value.indexOf('"') == -1 ? '"' : '\'';
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write(q);
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writeEscaped(value, q);
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write(q);
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return this;
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void flush() throws IOException {
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.flush();
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void close() throws IOException {
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            check();
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.close();
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    */
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public XmlSerializer endTag(String namespace, String name)
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!pending)
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            depth--;
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //        if (namespace == null)
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //          namespace = "";
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((namespace == null
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            && elementStack[depth * 3] != null)
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            || (namespace != null
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && !namespace.equals(elementStack[depth * 3]))
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            || !elementStack[depth * 3 + 2].equals(name))
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException("</{"+namespace+"}"+name+"> does not match start");
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (pending) {
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            check(true);
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            depth--;
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        else {
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (indent[depth + 1]) {
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                writer.write("\r\n");
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 0; i < depth; i++)
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    writer.write("  ");
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write("</");
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String prefix = elementStack[depth * 3 + 1];
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!"".equals(prefix)) {
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                writer.write(prefix);
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                writer.write(':');
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write(name);
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            writer.write('>');
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nspCounts[depth + 1] = nspCounts[depth];
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return this;
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getNamespace() {
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 3];
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getName() {
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 1];
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getDepth() {
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return pending ? depth + 1 : depth;
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public XmlSerializer text(String text) throws IOException {
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        indent[depth] = false;
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writeEscaped(text, -1);
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return this;
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public XmlSerializer text(char[] text, int start, int len)
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        text(new String(text, start, len));
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return this;
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void cdsect(String data) throws IOException {
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
558ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes        // BEGIN android-changed: ]]> is not allowed within a CDATA,
559ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes        // so break and start a new one when necessary.
560ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes        data = data.replace("]]>", "]]]]><![CDATA[>");
561ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes        char[] chars = data.toCharArray();
562ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes        // We also aren't allowed any invalid characters.
563ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes        for (char ch : chars) {
564ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes            boolean valid = (ch >= 0x20 && ch <= 0xd7ff) ||
565ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    (ch == '\t' || ch == '\n' || ch == '\r') ||
566ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                    (ch >= 0xe000 && ch <= 0xfffd);
567ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes            if (!valid) {
568ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes                reportInvalidCharacter(ch);
569ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes            }
570ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes        }
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write("<![CDATA[");
572ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes        writer.write(chars, 0, chars.length);
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write("]]>");
574ff42219e3ea3d712f931ae7f26af236339b5cf23Elliott Hughes        // END android-changed
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void comment(String comment) throws IOException {
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write("<!--");
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write(comment);
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write("-->");
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void processingInstruction(String pi)
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws IOException {
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        check(false);
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write("<?");
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write(pi);
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        writer.write("?>");
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
592