All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.holoeverywhere.util.FastXmlSerializer Maven / Gradle / Ivy

There is a newer version: 1.6.8
Show newest version

package org.holoeverywhere.util;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;

import org.xmlpull.v1.XmlSerializer;

public class FastXmlSerializer implements XmlSerializer {
    private static final int BUFFER_LEN = 8192;

    private static final String ESCAPE_TABLE[] = new String[] {
            null, null,
            null, null, null, null, null, null, // 0-7
            null, null, null, null, null, null, null, null, // 8-15
            null, null, null, null, null, null, null, null, // 16-23
            null, null, null, null, null, null, null, null, // 24-31
            null, null, """, null, null, null, "&", null, // 32-39
            null, null, null, null, null, null, null, null, // 40-47
            null, null, null, null, null, null, null, null, // 48-55
            null, null, null, null, "<", null, ">", null, // 56-63
    };

    private ByteBuffer mBytes = ByteBuffer
            .allocate(FastXmlSerializer.BUFFER_LEN);
    private CharsetEncoder mCharset;

    private boolean mInTag;

    private OutputStream mOutputStream;
    private int mPos;
    private final char[] mText = new char[FastXmlSerializer.BUFFER_LEN];

    private Writer mWriter;

    private void append(char c) throws IOException {
        int pos = mPos;
        if (pos >= FastXmlSerializer.BUFFER_LEN - 1) {
            flush();
            pos = mPos;
        }
        mText[pos] = c;
        mPos = pos + 1;
    }

    private void append(char[] buf, int i, final int length) throws IOException {
        if (length > FastXmlSerializer.BUFFER_LEN) {
            final int end = i + length;
            while (i < end) {
                int next = i + FastXmlSerializer.BUFFER_LEN;
                append(buf, i, next < end ? FastXmlSerializer.BUFFER_LEN : end
                        - i);
                i = next;
            }
            return;
        }
        int pos = mPos;
        if (pos + length > FastXmlSerializer.BUFFER_LEN) {
            flush();
            pos = mPos;
        }
        System.arraycopy(buf, i, mText, pos, length);
        mPos = pos + length;
    }

    private void append(String str) throws IOException {
        append(str, 0, str.length());
    }

    private void append(String str, int i, final int length) throws IOException {
        if (length > FastXmlSerializer.BUFFER_LEN) {
            final int end = i + length;
            while (i < end) {
                int next = i + FastXmlSerializer.BUFFER_LEN;
                append(str, i, next < end ? FastXmlSerializer.BUFFER_LEN : end
                        - i);
                i = next;
            }
            return;
        }
        int pos = mPos;
        if (pos + length > FastXmlSerializer.BUFFER_LEN) {
            flush();
            pos = mPos;
        }
        str.getChars(i, i + length, mText, pos);
        mPos = pos + length;
    }

    @Override
    public XmlSerializer attribute(String namespace, String name, String value)
            throws IOException, IllegalArgumentException, IllegalStateException {
        append(' ');
        if (namespace != null) {
            append(namespace);
            append(':');
        }
        append(name);
        append("=\"");

        escapeAndAppendString(value);
        append('"');
        return this;
    }

    @Override
    public void cdsect(String text) throws IOException,
            IllegalArgumentException, IllegalStateException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void comment(String text) throws IOException,
            IllegalArgumentException, IllegalStateException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void docdecl(String text) throws IOException,
            IllegalArgumentException, IllegalStateException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void endDocument() throws IOException, IllegalArgumentException,
            IllegalStateException {
        flush();
    }

    @Override
    public XmlSerializer endTag(String namespace, String name)
            throws IOException, IllegalArgumentException, IllegalStateException {
        if (mInTag) {
            append(" />\n");
        } else {
            append("\n");
        }
        mInTag = false;
        return this;
    }

    @Override
    public void entityRef(String text) throws IOException,
            IllegalArgumentException, IllegalStateException {
        throw new UnsupportedOperationException();
    }

    private void escapeAndAppendString(char[] buf, int start, int len)
            throws IOException {
        final char NE = (char) FastXmlSerializer.ESCAPE_TABLE.length;
        final String[] escapes = FastXmlSerializer.ESCAPE_TABLE;
        int end = start + len;
        int lastPos = start;
        int pos;
        for (pos = start; pos < end; pos++) {
            char c = buf[pos];
            if (c >= NE) {
                continue;
            }
            String escape = escapes[c];
            if (escape == null) {
                continue;
            }
            if (lastPos < pos) {
                append(buf, lastPos, pos - lastPos);
            }
            lastPos = pos + 1;
            append(escape);
        }
        if (lastPos < pos) {
            append(buf, lastPos, pos - lastPos);
        }
    }

    private void escapeAndAppendString(final String string) throws IOException {
        final int N = string.length();
        final char NE = (char) FastXmlSerializer.ESCAPE_TABLE.length;
        final String[] escapes = FastXmlSerializer.ESCAPE_TABLE;
        int lastPos = 0;
        int pos;
        for (pos = 0; pos < N; pos++) {
            char c = string.charAt(pos);
            if (c >= NE) {
                continue;
            }
            String escape = escapes[c];
            if (escape == null) {
                continue;
            }
            if (lastPos < pos) {
                append(string, lastPos, pos - lastPos);
            }
            lastPos = pos + 1;
            append(escape);
        }
        if (lastPos < pos) {
            append(string, lastPos, pos - lastPos);
        }
    }

    @Override
    public void flush() throws IOException {
        // Log.i("PackageManager", "flush mPos=" + mPos);
        if (mPos > 0) {
            if (mOutputStream != null) {
                CharBuffer charBuffer = CharBuffer.wrap(mText, 0, mPos);
                CoderResult result = mCharset.encode(charBuffer, mBytes, true);
                while (true) {
                    if (result.isError()) {
                        throw new IOException(result.toString());
                    } else if (result.isOverflow()) {
                        flushBytes();
                        result = mCharset.encode(charBuffer, mBytes, true);
                        continue;
                    }
                    break;
                }
                flushBytes();
                mOutputStream.flush();
            } else {
                mWriter.write(mText, 0, mPos);
                mWriter.flush();
            }
            mPos = 0;
        }
    }

    private void flushBytes() throws IOException {
        int position;
        if ((position = mBytes.position()) > 0) {
            mBytes.flip();
            mOutputStream.write(mBytes.array(), 0, position);
            mBytes.clear();
        }
    }

    @Override
    public int getDepth() {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean getFeature(String name) {
        throw new UnsupportedOperationException();
    }

    @Override
    public String getName() {
        throw new UnsupportedOperationException();
    }

    @Override
    public String getNamespace() {
        throw new UnsupportedOperationException();
    }

    @Override
    public String getPrefix(String namespace, boolean generatePrefix)
            throws IllegalArgumentException {
        throw new UnsupportedOperationException();
    }

    @Override
    public Object getProperty(String name) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void ignorableWhitespace(String text) throws IOException,
            IllegalArgumentException, IllegalStateException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void processingInstruction(String text) throws IOException,
            IllegalArgumentException, IllegalStateException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void setFeature(String name, boolean state)
            throws IllegalArgumentException, IllegalStateException {
        if (name.equals("http://xmlpull.org/v1/doc/features.html#indent-output")) {
            return;
        }
        throw new UnsupportedOperationException();
    }

    @Override
    public void setOutput(OutputStream os, String encoding) throws IOException,
            IllegalArgumentException, IllegalStateException {
        if (os == null) {
            throw new IllegalArgumentException();
        }
        try {
            mCharset = Charset.forName(encoding).newEncoder();
        } catch (IllegalCharsetNameException e) {
            throw (UnsupportedEncodingException) new UnsupportedEncodingException(
                    encoding).initCause(e);
        } catch (UnsupportedCharsetException e) {
            throw (UnsupportedEncodingException) new UnsupportedEncodingException(
                    encoding).initCause(e);
        }
        mOutputStream = os;
    }

    @Override
    public void setOutput(Writer writer) throws IOException,
            IllegalArgumentException, IllegalStateException {
        mWriter = writer;
    }

    @Override
    public void setPrefix(String prefix, String namespace) throws IOException,
            IllegalArgumentException, IllegalStateException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void setProperty(String name, Object value)
            throws IllegalArgumentException, IllegalStateException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void startDocument(String encoding, Boolean standalone)
            throws IOException, IllegalArgumentException, IllegalStateException {
        append("\n");
    }

    @Override
    public XmlSerializer startTag(String namespace, String name)
            throws IOException, IllegalArgumentException, IllegalStateException {
        if (mInTag) {
            append(">\n");
        }
        append('<');
        if (namespace != null) {
            append(namespace);
            append(':');
        }
        append(name);
        mInTag = true;
        return this;
    }

    @Override
    public XmlSerializer text(char[] buf, int start, int len)
            throws IOException, IllegalArgumentException, IllegalStateException {
        if (mInTag) {
            append(">");
            mInTag = false;
        }
        escapeAndAppendString(buf, start, len);
        return this;
    }

    @Override
    public XmlSerializer text(String text) throws IOException,
            IllegalArgumentException, IllegalStateException {
        if (mInTag) {
            append(">");
            mInTag = false;
        }
        escapeAndAppendString(text);
        return this;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy