mirror of
https://github.com/revanced/Apktool.git
synced 2025-05-03 15:24:26 +02:00
style: reorganize MXSerializer
This commit is contained in:
parent
3037024022
commit
f1357109aa
@ -25,7 +25,7 @@ import org.xmlpull.v1.XmlSerializer;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of XmlSerializer interface from XmlPull V1 API. This
|
* Implementation of XmlSerializer interface from XmlPull V1 API. This
|
||||||
* implementation is optimzied for performance and low memory footprint.
|
* implementation is optimized for performance and low memory footprint.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Implemented features:
|
* Implemented features:
|
||||||
@ -90,9 +90,8 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
protected boolean seenBracket;
|
protected boolean seenBracket;
|
||||||
protected boolean seenBracketBracket;
|
protected boolean seenBracketBracket;
|
||||||
|
|
||||||
// buffer output if neede to write escaped String see text(String)
|
// buffer output if needed to write escaped String see text(String)
|
||||||
private static final int BUF_LEN = Runtime.getRuntime().freeMemory() > 1000000L ? 8 * 1024
|
private static final int BUF_LEN = Runtime.getRuntime().freeMemory() > 1000000L ? 8 * 1024 : 256;
|
||||||
: 256;
|
|
||||||
protected char buf[] = new char[BUF_LEN];
|
protected char buf[] = new char[BUF_LEN];
|
||||||
|
|
||||||
protected static final String precomputedPrefixes[];
|
protected static final String precomputedPrefixes[];
|
||||||
@ -108,9 +107,8 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
|
|
||||||
private void checkInterning(String name) {
|
private void checkInterning(String name) {
|
||||||
if (namesInterned && name != name.intern()) {
|
if (namesInterned && name != name.intern()) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("all names passed as arguments must be interned"
|
||||||
"all names passed as arguments must be interned"
|
+ "when NAMES INTERNED feature is enabled");
|
||||||
+ "when NAMES INTERNED feature is enabled");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,16 +128,8 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
|
|
||||||
namespaceEnd = 0;
|
namespaceEnd = 0;
|
||||||
|
|
||||||
// NOTE: no need to intern() as all literal strings and string-valued
|
|
||||||
// constant expressions
|
|
||||||
// are interned. String literals are defined in 3.10.5 of the Java
|
|
||||||
// Language Specification
|
|
||||||
// just checking ...
|
|
||||||
// assert "xmlns" == "xmlns".intern();
|
|
||||||
// assert XMLNS_URI == XMLNS_URI.intern();
|
|
||||||
|
|
||||||
// TODO: how to prevent from reporting this namespace?
|
// TODO: how to prevent from reporting this namespace?
|
||||||
// this is special namespace declared for consistensy with XML infoset
|
// this is special namespace declared for consistency with XML infoset
|
||||||
namespacePrefix[namespaceEnd] = "xmlns";
|
namespacePrefix[namespaceEnd] = "xmlns";
|
||||||
namespaceUri[namespaceEnd] = XMLNS_URI;
|
namespaceUri[namespaceEnd] = XMLNS_URI;
|
||||||
++namespaceEnd;
|
++namespaceEnd;
|
||||||
@ -152,7 +142,6 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
pastRoot = false;
|
pastRoot = false;
|
||||||
setPrefixCalled = false;
|
setPrefixCalled = false;
|
||||||
startTagIncomplete = false;
|
startTagIncomplete = false;
|
||||||
// doIntent is not changed
|
|
||||||
seenTag = false;
|
seenTag = false;
|
||||||
|
|
||||||
seenBracket = false;
|
seenBracket = false;
|
||||||
@ -161,10 +150,8 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
|
|
||||||
protected void ensureElementsCapacity() {
|
protected void ensureElementsCapacity() {
|
||||||
final int elStackSize = elName.length;
|
final int elStackSize = elName.length;
|
||||||
// assert (depth + 1) >= elName.length;
|
final int newSize = (depth >= 7 ? 2 * depth : 8) + 2;
|
||||||
// we add at least one extra slot ...
|
|
||||||
final int newSize = (depth >= 7 ? 2 * depth : 8) + 2; // = lucky 7 + 1
|
|
||||||
// //25
|
|
||||||
if (TRACE_SIZING) {
|
if (TRACE_SIZING) {
|
||||||
System.err.println(getClass().getName() + " elStackSize "
|
System.err.println(getClass().getName() + " elStackSize "
|
||||||
+ elStackSize + " ==> " + newSize);
|
+ elStackSize + " ==> " + newSize);
|
||||||
@ -198,39 +185,18 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void ensureNamespacesCapacity() { // int size) {
|
protected void ensureNamespacesCapacity() { // int size) {
|
||||||
// int namespaceSize = namespacePrefix != null ? namespacePrefix.length
|
|
||||||
// : 0;
|
|
||||||
// assert (namespaceEnd >= namespacePrefix.length);
|
|
||||||
|
|
||||||
// if(size >= namespaceSize) {
|
|
||||||
// int newSize = size > 7 ? 2 * size : 8; // = lucky 7 + 1 //25
|
|
||||||
final int newSize = namespaceEnd > 7 ? 2 * namespaceEnd : 8;
|
final int newSize = namespaceEnd > 7 ? 2 * namespaceEnd : 8;
|
||||||
if (TRACE_SIZING) {
|
if (TRACE_SIZING) {
|
||||||
System.err.println(getClass().getName() + " namespaceSize "
|
System.err.println(getClass().getName() + " namespaceSize " + namespacePrefix.length + " ==> " + newSize);
|
||||||
+ namespacePrefix.length + " ==> " + newSize);
|
|
||||||
}
|
}
|
||||||
final String[] newNamespacePrefix = new String[newSize];
|
final String[] newNamespacePrefix = new String[newSize];
|
||||||
final String[] newNamespaceUri = new String[newSize];
|
final String[] newNamespaceUri = new String[newSize];
|
||||||
if (namespacePrefix != null) {
|
if (namespacePrefix != null) {
|
||||||
System.arraycopy(namespacePrefix, 0, newNamespacePrefix, 0,
|
System.arraycopy(namespacePrefix, 0, newNamespacePrefix, 0, namespaceEnd);
|
||||||
namespaceEnd);
|
|
||||||
System.arraycopy(namespaceUri, 0, newNamespaceUri, 0, namespaceEnd);
|
System.arraycopy(namespaceUri, 0, newNamespaceUri, 0, namespaceEnd);
|
||||||
}
|
}
|
||||||
namespacePrefix = newNamespacePrefix;
|
namespacePrefix = newNamespacePrefix;
|
||||||
namespaceUri = newNamespaceUri;
|
namespaceUri = newNamespaceUri;
|
||||||
|
|
||||||
// TODO use hashes for quick namespace->prefix lookups
|
|
||||||
// if( ! allStringsInterned ) {
|
|
||||||
// int[] newNamespacePrefixHash = new int[newSize];
|
|
||||||
// if(namespacePrefixHash != null) {
|
|
||||||
// System.arraycopy(
|
|
||||||
// namespacePrefixHash, 0, newNamespacePrefixHash, 0, namespaceEnd);
|
|
||||||
// }
|
|
||||||
// namespacePrefixHash = newNamespacePrefixHash;
|
|
||||||
// }
|
|
||||||
// prefixesSize = newSize;
|
|
||||||
// ////assert nsPrefixes.length > size && nsPrefixes.length == newSize
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -278,8 +244,7 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
protected void rebuildIndentationBuf() {
|
protected void rebuildIndentationBuf() {
|
||||||
if (doIndent == false)
|
if (doIndent == false)
|
||||||
return;
|
return;
|
||||||
final int maxIndent = 65; // hardcoded maximum indentation size in
|
final int maxIndent = 65; // hardcoded maximum indentation size in characters
|
||||||
// characters
|
|
||||||
int bufSize = 0;
|
int bufSize = 0;
|
||||||
offsetNewLine = 0;
|
offsetNewLine = 0;
|
||||||
if (writeLineSepartor) {
|
if (writeLineSepartor) {
|
||||||
@ -310,12 +275,11 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(doIndent) writeIndent();
|
|
||||||
protected void writeIndent() throws IOException {
|
protected void writeIndent() throws IOException {
|
||||||
final int start = writeLineSepartor ? 0 : offsetNewLine;
|
final int start = writeLineSepartor ? 0 : offsetNewLine;
|
||||||
final int level = (depth > maxIndentLevel) ? maxIndentLevel : depth;
|
final int level = (depth > maxIndentLevel) ? maxIndentLevel : depth;
|
||||||
out.write(indentationBuf, start, ((level - 1) * indentationJump)
|
|
||||||
+ offsetNewLine);
|
out.write(indentationBuf, start, ((level - 1) * indentationJump) + offsetNewLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -392,7 +356,6 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
@Override
|
@Override
|
||||||
public void startDocument(String encoding, Boolean standalone)
|
public void startDocument(String encoding, Boolean standalone)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
char apos = attributeUseApostrophe ? '\'' : '"';
|
|
||||||
if (attributeUseApostrophe) {
|
if (attributeUseApostrophe) {
|
||||||
out.write("<?xml version='1.0'");
|
out.write("<?xml version='1.0'");
|
||||||
} else {
|
} else {
|
||||||
@ -403,7 +366,6 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
out.write(attributeUseApostrophe ? '\'' : '"');
|
out.write(attributeUseApostrophe ? '\'' : '"');
|
||||||
out.write(encoding);
|
out.write(encoding);
|
||||||
out.write(attributeUseApostrophe ? '\'' : '"');
|
out.write(attributeUseApostrophe ? '\'' : '"');
|
||||||
// out.write('\'');
|
|
||||||
}
|
}
|
||||||
if (standalone != null) {
|
if (standalone != null) {
|
||||||
out.write(" standalone=");
|
out.write(" standalone=");
|
||||||
@ -414,11 +376,6 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
out.write("no");
|
out.write("no");
|
||||||
}
|
}
|
||||||
out.write(attributeUseApostrophe ? '\'' : '"');
|
out.write(attributeUseApostrophe ? '\'' : '"');
|
||||||
// if(standalone.booleanValue()) {
|
|
||||||
// out.write(" standalone='yes'");
|
|
||||||
// } else {
|
|
||||||
// out.write(" standalone='no'");
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
out.write("?>");
|
out.write("?>");
|
||||||
}
|
}
|
||||||
@ -429,8 +386,6 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
while (depth > 0) {
|
while (depth > 0) {
|
||||||
endTag(elNamespace[depth], elName[depth]);
|
endTag(elNamespace[depth], elName[depth]);
|
||||||
}
|
}
|
||||||
// assert depth == 0;
|
|
||||||
// assert startTagIncomplete == false;
|
|
||||||
finished = pastRoot = startTagIncomplete = true;
|
finished = pastRoot = startTagIncomplete = true;
|
||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
@ -439,8 +394,7 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
public void setPrefix(String prefix, String namespace) throws IOException {
|
public void setPrefix(String prefix, String namespace) throws IOException {
|
||||||
if (startTagIncomplete)
|
if (startTagIncomplete)
|
||||||
closeStartTag();
|
closeStartTag();
|
||||||
// assert prefix != null;
|
|
||||||
// assert namespace != null;
|
|
||||||
if (prefix == null) {
|
if (prefix == null) {
|
||||||
prefix = "";
|
prefix = "";
|
||||||
}
|
}
|
||||||
@ -449,8 +403,7 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
} else if (checkNamesInterned) {
|
} else if (checkNamesInterned) {
|
||||||
checkInterning(prefix);
|
checkInterning(prefix);
|
||||||
} else if (prefix == null) {
|
} else if (prefix == null) {
|
||||||
throw new IllegalArgumentException("prefix must be not null"
|
throw new IllegalArgumentException("prefix must be not null" + getLocation());
|
||||||
+ getLocation());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that prefix is not duplicated ...
|
// check that prefix is not duplicated ...
|
||||||
@ -466,8 +419,7 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
} else if (checkNamesInterned) {
|
} else if (checkNamesInterned) {
|
||||||
checkInterning(namespace);
|
checkInterning(namespace);
|
||||||
} else if (namespace == null) {
|
} else if (namespace == null) {
|
||||||
throw new IllegalArgumentException("namespace must be not null"
|
throw new IllegalArgumentException("namespace must be not null" + getLocation());
|
||||||
+ getLocation());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (namespaceEnd >= namespacePrefix.length) {
|
if (namespaceEnd >= namespacePrefix.length) {
|
||||||
@ -490,21 +442,16 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
|
|
||||||
protected String getPrefix(String namespace, boolean generatePrefix,
|
protected String getPrefix(String namespace, boolean generatePrefix,
|
||||||
boolean nonEmpty) {
|
boolean nonEmpty) {
|
||||||
// assert namespace != null;
|
|
||||||
if (!namesInterned) {
|
if (!namesInterned) {
|
||||||
// when String is interned we can do much faster namespace stack
|
// when String is interned we can do much faster namespace stack lookups ...
|
||||||
// lookups ...
|
|
||||||
namespace = namespace.intern();
|
namespace = namespace.intern();
|
||||||
} else if (checkNamesInterned) {
|
} else if (checkNamesInterned) {
|
||||||
checkInterning(namespace);
|
checkInterning(namespace);
|
||||||
// assert namespace != namespace.intern();
|
|
||||||
}
|
}
|
||||||
if (namespace == null) {
|
if (namespace == null) {
|
||||||
throw new IllegalArgumentException("namespace must be not null"
|
throw new IllegalArgumentException("namespace must be not null" + getLocation());
|
||||||
+ getLocation());
|
|
||||||
} else if (namespace.length() == 0) {
|
} else if (namespace.length() == 0) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("default namespace cannot have prefix" + getLocation());
|
||||||
"default namespace cannot have prefix" + getLocation());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// first check if namespace is already in scope
|
// first check if namespace is already in scope
|
||||||
@ -516,8 +463,7 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
// now check that prefix is still in scope
|
// now check that prefix is still in scope
|
||||||
for (int p = namespaceEnd - 1; p > i; --p) {
|
for (int p = namespaceEnd - 1; p > i; --p) {
|
||||||
if (prefix == namespacePrefix[p])
|
if (prefix == namespacePrefix[p])
|
||||||
continue; // too bad - prefix is redeclared with
|
continue; // too bad - prefix is redeclared with different namespace
|
||||||
// different namespace
|
|
||||||
}
|
}
|
||||||
return prefix;
|
return prefix;
|
||||||
}
|
}
|
||||||
@ -531,18 +477,17 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String generatePrefix(String namespace) {
|
private String generatePrefix(String namespace) {
|
||||||
// assert namespace == namespace.intern();
|
|
||||||
while (true) {
|
while (true) {
|
||||||
++autoDeclaredPrefixes;
|
++autoDeclaredPrefixes;
|
||||||
// fast lookup uses table that was pre-initialized in static{} ....
|
// fast lookup uses table that was pre-initialized in static{} ....
|
||||||
final String prefix = autoDeclaredPrefixes < precomputedPrefixes.length ? precomputedPrefixes[autoDeclaredPrefixes]
|
final String prefix = autoDeclaredPrefixes < precomputedPrefixes.length
|
||||||
|
? precomputedPrefixes[autoDeclaredPrefixes]
|
||||||
: ("n" + autoDeclaredPrefixes).intern();
|
: ("n" + autoDeclaredPrefixes).intern();
|
||||||
// make sure this prefix is not declared in any scope (avoid hiding
|
|
||||||
// in-scope prefixes)!
|
// make sure this prefix is not declared in any scope (avoid hiding in-scope prefixes)!
|
||||||
for (int i = namespaceEnd - 1; i >= 0; --i) {
|
for (int i = namespaceEnd - 1; i >= 0; --i) {
|
||||||
if (prefix == namespacePrefix[i]) {
|
if (prefix == namespacePrefix[i]) {
|
||||||
continue; // prefix is already declared - generate new and
|
continue; // prefix is already declared - generate new and try again
|
||||||
// try again
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// declare prefix
|
// declare prefix
|
||||||
@ -590,42 +535,35 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
if ((depth + 1) >= elName.length) {
|
if ((depth + 1) >= elName.length) {
|
||||||
ensureElementsCapacity();
|
ensureElementsCapacity();
|
||||||
}
|
}
|
||||||
// //assert namespace != null;
|
|
||||||
|
|
||||||
if (checkNamesInterned && namesInterned)
|
if (checkNamesInterned && namesInterned)
|
||||||
checkInterning(namespace);
|
checkInterning(namespace);
|
||||||
elNamespace[depth] = (namesInterned || namespace == null) ? namespace
|
|
||||||
: namespace.intern();
|
elNamespace[depth] = (namesInterned || namespace == null) ? namespace : namespace.intern();
|
||||||
// assert name != null;
|
|
||||||
// elName[ depth ] = name;
|
|
||||||
if (checkNamesInterned && namesInterned)
|
if (checkNamesInterned && namesInterned)
|
||||||
checkInterning(name);
|
checkInterning(name);
|
||||||
|
|
||||||
elName[depth] = (namesInterned || name == null) ? name : name.intern();
|
elName[depth] = (namesInterned || name == null) ? name : name.intern();
|
||||||
if (out == null) {
|
if (out == null) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException("setOutput() must called set before serialization can start");
|
||||||
"setOutput() must called set before serialization can start");
|
|
||||||
}
|
}
|
||||||
out.write('<');
|
out.write('<');
|
||||||
if (namespace != null) {
|
if (namespace != null) {
|
||||||
if (namespace.length() > 0) {
|
if (namespace.length() > 0) {
|
||||||
// ALEK: in future make this algo a feature on serializer
|
// in future make this algo a feature on serializer
|
||||||
String prefix = null;
|
String prefix = null;
|
||||||
if (depth > 0
|
if (depth > 0 && (namespaceEnd - elNamespaceCount[depth - 1]) == 1) {
|
||||||
&& (namespaceEnd - elNamespaceCount[depth - 1]) == 1) {
|
|
||||||
// if only one prefix was declared un-declare it if the
|
// if only one prefix was declared un-declare it if the
|
||||||
// prefix is already declared on parent el with the same URI
|
// prefix is already declared on parent el with the same URI
|
||||||
String uri = namespaceUri[namespaceEnd - 1];
|
String uri = namespaceUri[namespaceEnd - 1];
|
||||||
if (uri == namespace || uri.equals(namespace)) {
|
if (uri == namespace || uri.equals(namespace)) {
|
||||||
String elPfx = namespacePrefix[namespaceEnd - 1];
|
String elPfx = namespacePrefix[namespaceEnd - 1];
|
||||||
// 2 == to skip predefined namesapces (xml and xmlns
|
|
||||||
// ...)
|
|
||||||
for (int pos = elNamespaceCount[depth - 1] - 1; pos >= 2; --pos) {
|
for (int pos = elNamespaceCount[depth - 1] - 1; pos >= 2; --pos) {
|
||||||
String pf = namespacePrefix[pos];
|
String pf = namespacePrefix[pos];
|
||||||
if (pf == elPfx || pf.equals(elPfx)) {
|
if (pf == elPfx || pf.equals(elPfx)) {
|
||||||
String n = namespaceUri[pos];
|
String n = namespaceUri[pos];
|
||||||
if (n == uri || n.equals(uri)) {
|
if (n == uri || n.equals(uri)) {
|
||||||
--namespaceEnd; // un-declare namespace:
|
--namespaceEnd; // un-declare namespace: this is kludge!
|
||||||
// this is kludge!
|
|
||||||
prefix = elPfx;
|
prefix = elPfx;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -636,7 +574,6 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
if (prefix == null) {
|
if (prefix == null) {
|
||||||
prefix = lookupOrDeclarePrefix(namespace);
|
prefix = lookupOrDeclarePrefix(namespace);
|
||||||
}
|
}
|
||||||
// assert prefix != null;
|
|
||||||
// make sure that default ("") namespace to not print ":"
|
// make sure that default ("") namespace to not print ":"
|
||||||
if (prefix.length() > 0) {
|
if (prefix.length() > 0) {
|
||||||
elPrefix[depth] = prefix;
|
elPrefix[depth] = prefix;
|
||||||
@ -651,13 +588,11 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
if (namespacePrefix[i] == "") {
|
if (namespacePrefix[i] == "") {
|
||||||
final String uri = namespaceUri[i];
|
final String uri = namespaceUri[i];
|
||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
// declare default namespace
|
|
||||||
setPrefix("", "");
|
setPrefix("", "");
|
||||||
} else if (uri.length() > 0) {
|
} else if (uri.length() > 0) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException("start tag can not be written in empty default namespace "
|
||||||
"start tag can not be written in empty default namespace "
|
+ "as default namespace is currently bound to '"
|
||||||
+ "as default namespace is currently bound to '"
|
+ uri + "'" + getLocation());
|
||||||
+ uri + "'" + getLocation());
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -675,23 +610,16 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
public XmlSerializer attribute(String namespace, String name, String value)
|
public XmlSerializer attribute(String namespace, String name, String value)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (!startTagIncomplete) {
|
if (!startTagIncomplete) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("startTag() must be called before attribute()" + getLocation());
|
||||||
"startTag() must be called before attribute()"
|
|
||||||
+ getLocation());
|
|
||||||
}
|
}
|
||||||
// assert setPrefixCalled == false;
|
|
||||||
out.write(' ');
|
out.write(' ');
|
||||||
// //assert namespace != null;
|
|
||||||
if (namespace != null && namespace.length() > 0) {
|
if (namespace != null && namespace.length() > 0) {
|
||||||
// namespace = namespace.intern();
|
|
||||||
if (!namesInterned) {
|
if (!namesInterned) {
|
||||||
namespace = namespace.intern();
|
namespace = namespace.intern();
|
||||||
} else if (checkNamesInterned) {
|
} else if (checkNamesInterned) {
|
||||||
checkInterning(namespace);
|
checkInterning(namespace);
|
||||||
}
|
}
|
||||||
String prefix = getPrefix(namespace, false, true);
|
String prefix = getPrefix(namespace, false, true);
|
||||||
// assert( prefix != null);
|
|
||||||
// if(prefix.length() == 0) {
|
|
||||||
if (prefix == null) {
|
if (prefix == null) {
|
||||||
// needs to declare prefix to hold default namespace
|
// needs to declare prefix to hold default namespace
|
||||||
// NOTE: attributes such as a='b' are in NO namespace
|
// NOTE: attributes such as a='b' are in NO namespace
|
||||||
@ -699,15 +627,9 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
}
|
}
|
||||||
out.write(prefix);
|
out.write(prefix);
|
||||||
out.write(':');
|
out.write(':');
|
||||||
// if(prefix.length() > 0) {
|
|
||||||
// out.write(prefix);
|
|
||||||
// out.write(':');
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
// assert name != null;
|
|
||||||
out.write(name);
|
out.write(name);
|
||||||
out.write('=');
|
out.write('=');
|
||||||
// assert value != null;
|
|
||||||
out.write(attributeUseApostrophe ? '\'' : '"');
|
out.write(attributeUseApostrophe ? '\'' : '"');
|
||||||
writeAttributeValue(value, out);
|
writeAttributeValue(value, out);
|
||||||
out.write(attributeUseApostrophe ? '\'' : '"');
|
out.write(attributeUseApostrophe ? '\'' : '"');
|
||||||
@ -716,26 +638,23 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
|
|
||||||
protected void closeStartTag() throws IOException {
|
protected void closeStartTag() throws IOException {
|
||||||
if (finished) {
|
if (finished) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("trying to write past already finished output"
|
||||||
"trying to write past already finished output"
|
+ getLocation());
|
||||||
+ getLocation());
|
|
||||||
}
|
}
|
||||||
if (seenBracket) {
|
if (seenBracket) {
|
||||||
seenBracket = seenBracketBracket = false;
|
seenBracket = seenBracketBracket = false;
|
||||||
}
|
}
|
||||||
if (startTagIncomplete || setPrefixCalled) {
|
if (startTagIncomplete || setPrefixCalled) {
|
||||||
if (setPrefixCalled) {
|
if (setPrefixCalled) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("startTag() must be called immediately after setPrefix()"
|
||||||
"startTag() must be called immediately after setPrefix()"
|
+ getLocation());
|
||||||
+ getLocation());
|
|
||||||
}
|
}
|
||||||
if (!startTagIncomplete) {
|
if (!startTagIncomplete) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("trying to close start tag that is not opened"
|
||||||
"trying to close start tag that is not opened"
|
+ getLocation());
|
||||||
+ getLocation());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// write all namespace delcarations!
|
// write all namespace declarations!
|
||||||
writeNamespaceDeclarations();
|
writeNamespaceDeclarations();
|
||||||
out.write('>');
|
out.write('>');
|
||||||
elNamespaceCount[depth] = namespaceEnd;
|
elNamespaceCount[depth] = namespaceEnd;
|
||||||
@ -744,7 +663,6 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void writeNamespaceDeclarations() throws IOException {
|
protected void writeNamespaceDeclarations() throws IOException {
|
||||||
// int start = elNamespaceCount[ depth - 1 ];
|
|
||||||
for (int i = elNamespaceCount[depth - 1]; i < namespaceEnd; i++) {
|
for (int i = elNamespaceCount[depth - 1]; i < namespaceEnd; i++) {
|
||||||
if (doIndent && namespaceUri[i].length() > 40) {
|
if (doIndent && namespaceUri[i].length() > 40) {
|
||||||
writeIndent();
|
writeIndent();
|
||||||
@ -761,7 +679,6 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
|
|
||||||
// NOTE: escaping of namespace value the same way as attributes!!!!
|
// NOTE: escaping of namespace value the same way as attributes!!!!
|
||||||
writeAttributeValue(namespaceUri[i], out);
|
writeAttributeValue(namespaceUri[i], out);
|
||||||
|
|
||||||
out.write(attributeUseApostrophe ? '\'' : '"');
|
out.write(attributeUseApostrophe ? '\'' : '"');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -769,11 +686,6 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
@Override
|
@Override
|
||||||
public XmlSerializer endTag(String namespace, String name)
|
public XmlSerializer endTag(String namespace, String name)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
// check that level is valid
|
|
||||||
// //assert namespace != null;
|
|
||||||
// if(namespace != null) {
|
|
||||||
// namespace = namespace.intern();
|
|
||||||
// }
|
|
||||||
seenBracket = seenBracketBracket = false;
|
seenBracket = seenBracketBracket = false;
|
||||||
if (namespace != null) {
|
if (namespace != null) {
|
||||||
if (!namesInterned) {
|
if (!namesInterned) {
|
||||||
@ -784,31 +696,25 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (namespace != elNamespace[depth]) {
|
if (namespace != elNamespace[depth]) {
|
||||||
throw new IllegalArgumentException("expected namespace "
|
throw new IllegalArgumentException("expected namespace " + printable(elNamespace[depth]) + " and not "
|
||||||
+ printable(elNamespace[depth]) + " and not "
|
|
||||||
+ printable(namespace) + getLocation());
|
+ printable(namespace) + getLocation());
|
||||||
}
|
}
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
throw new IllegalArgumentException("end tag name can not be null"
|
throw new IllegalArgumentException("end tag name can not be null" + getLocation());
|
||||||
+ getLocation());
|
|
||||||
}
|
}
|
||||||
if (checkNamesInterned && namesInterned) {
|
if (checkNamesInterned && namesInterned) {
|
||||||
checkInterning(name);
|
checkInterning(name);
|
||||||
}
|
}
|
||||||
String startTagName = elName[depth];
|
String startTagName = elName[depth];
|
||||||
if ((!namesInterned && !name.equals(startTagName))
|
if ((!namesInterned && !name.equals(startTagName)) || (namesInterned && name != startTagName)) {
|
||||||
|| (namesInterned && name != startTagName)) {
|
|
||||||
throw new IllegalArgumentException("expected element name "
|
throw new IllegalArgumentException("expected element name "
|
||||||
+ printable(elName[depth]) + " and not " + printable(name)
|
+ printable(elName[depth]) + " and not " + printable(name) + getLocation());
|
||||||
+ getLocation());
|
|
||||||
}
|
}
|
||||||
if (startTagIncomplete) {
|
if (startTagIncomplete) {
|
||||||
writeNamespaceDeclarations();
|
writeNamespaceDeclarations();
|
||||||
out.write(" />"); // space is added to make it easier to work in
|
out.write(" />"); // space is added to make it easier to work in XHTML!!!
|
||||||
// XHTML!!!
|
|
||||||
--depth;
|
--depth;
|
||||||
} else {
|
} else {
|
||||||
// assert startTagIncomplete == false;
|
|
||||||
if (doIndent && seenTag) {
|
if (doIndent && seenTag) {
|
||||||
writeIndent();
|
writeIndent();
|
||||||
}
|
}
|
||||||
@ -818,16 +724,6 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
out.write(startTagPrefix);
|
out.write(startTagPrefix);
|
||||||
out.write(':');
|
out.write(':');
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(namespace != null && namespace.length() > 0) {
|
|
||||||
// //TODO prefix should be alredy known from matching start tag ...
|
|
||||||
// final String prefix = lookupOrDeclarePrefix( namespace );
|
|
||||||
// //assert( prefix != null);
|
|
||||||
// if(prefix.length() > 0) {
|
|
||||||
// out.write(prefix);
|
|
||||||
// out.write(':');
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
out.write(name);
|
out.write(name);
|
||||||
out.write('>');
|
out.write('>');
|
||||||
--depth;
|
--depth;
|
||||||
@ -840,7 +736,6 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XmlSerializer text(String text) throws IOException {
|
public XmlSerializer text(String text) throws IOException {
|
||||||
// assert text != null;
|
|
||||||
if (startTagIncomplete || setPrefixCalled)
|
if (startTagIncomplete || setPrefixCalled)
|
||||||
closeStartTag();
|
closeStartTag();
|
||||||
if (doIndent && seenTag)
|
if (doIndent && seenTag)
|
||||||
@ -922,9 +817,7 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
if (doIndent && seenTag)
|
if (doIndent && seenTag)
|
||||||
seenTag = false;
|
seenTag = false;
|
||||||
if (text.length() == 0) {
|
if (text.length() == 0) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("empty string is not allowed for ignorable whitespace" + getLocation());
|
||||||
"empty string is not allowed for ignorable whitespace"
|
|
||||||
+ getLocation());
|
|
||||||
}
|
}
|
||||||
out.write(text); // no escape?
|
out.write(text); // no escape?
|
||||||
}
|
}
|
||||||
@ -976,28 +869,13 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
pos = i + 1;
|
pos = i + 1;
|
||||||
} else {
|
} else {
|
||||||
if (TRACE_ESCAPING)
|
if (TRACE_ESCAPING)
|
||||||
System.err.println(getClass().getName()
|
System.err.println(getClass().getName() + " DEBUG ATTR value.len=" + value.length()
|
||||||
+ " DEBUG ATTR value.len=" + value.length()
|
|
||||||
+ " " + printable(value));
|
+ " " + printable(value));
|
||||||
|
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
// "character "+Integer.toString(ch)+" is not allowed in output"+getLocation());
|
"character " + printable(ch) + " (" + Integer.toString(ch) + ") is not allowed in output"
|
||||||
"character " + printable(ch) + " ("
|
|
||||||
+ Integer.toString(ch)
|
|
||||||
+ ") is not allowed in output"
|
|
||||||
+ getLocation() + " (attr value="
|
+ getLocation() + " (attr value="
|
||||||
+ printable(value) + ")");
|
+ printable(value) + ")");
|
||||||
// in XML 1.1 legal are [#x1-#xD7FF]
|
|
||||||
// if(ch > 0) {
|
|
||||||
// if(i > pos) out.write(text.substring(pos, i));
|
|
||||||
// out.write("&#");
|
|
||||||
// out.write(Integer.toString(ch));
|
|
||||||
// out.write(';');
|
|
||||||
// pos = i + 1;
|
|
||||||
// } else {
|
|
||||||
// throw new IllegalStateException(
|
|
||||||
// "character zero is not allowed in XML 1.1 output"+getLocation());
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1006,12 +884,11 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
} else {
|
} else {
|
||||||
out.write(value); // this is shortcut to the most common case
|
out.write(value); // this is shortcut to the most common case
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeElementContent(String text, Writer out)
|
protected void writeElementContent(String text, Writer out)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
// esccape '<', '&', ']]>', <32 if necessary
|
// escape '<', '&', ']]>', <32 if necessary
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
for (int i = 0; i < text.length(); i++) {
|
for (int i = 0; i < text.length(); i++) {
|
||||||
// TODO: check if doing char[] text.getChars() would be faster than
|
// TODO: check if doing char[] text.getChars() would be faster than
|
||||||
@ -1046,33 +923,13 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
// in XML 1.0 only legal character are #x9 | #xA | #xD
|
// in XML 1.0 only legal character are #x9 | #xA | #xD
|
||||||
if (ch == 9 || ch == 10 || ch == 13) {
|
if (ch == 9 || ch == 10 || ch == 13) {
|
||||||
// pass through
|
// pass through
|
||||||
|
|
||||||
// } else if(ch == 13) { //escape
|
|
||||||
// if(i > pos) out.write(text.substring(pos, i));
|
|
||||||
// out.write("&#");
|
|
||||||
// out.write(Integer.toString(ch));
|
|
||||||
// out.write(';');
|
|
||||||
// pos = i + 1;
|
|
||||||
} else {
|
} else {
|
||||||
if (TRACE_ESCAPING)
|
if (TRACE_ESCAPING)
|
||||||
System.err.println(getClass().getName()
|
System.err.println(getClass().getName() + " DEBUG TEXT value.len=" + text.length()
|
||||||
+ " DEBUG TEXT value.len=" + text.length()
|
|
||||||
+ " " + printable(text));
|
+ " " + printable(text));
|
||||||
throw new IllegalStateException("character "
|
throw new IllegalStateException("character " + Integer.toString(ch)
|
||||||
+ Integer.toString(ch)
|
|
||||||
+ " is not allowed in output" + getLocation()
|
+ " is not allowed in output" + getLocation()
|
||||||
+ " (text value=" + printable(text) + ")");
|
+ " (text value=" + printable(text) + ")");
|
||||||
// in XML 1.1 legal are [#x1-#xD7FF]
|
|
||||||
// if(ch > 0) {
|
|
||||||
// if(i > pos) out.write(text.substring(pos, i));
|
|
||||||
// out.write("&#");
|
|
||||||
// out.write(Integer.toString(ch));
|
|
||||||
// out.write(';');
|
|
||||||
// pos = i + 1;
|
|
||||||
// } else {
|
|
||||||
// throw new IllegalStateException(
|
|
||||||
// "character zero is not allowed in XML 1.1 output"+getLocation());
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (seenBracket) {
|
if (seenBracket) {
|
||||||
@ -1091,7 +948,7 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
|
|
||||||
protected void writeElementContent(char[] buf, int off, int len, Writer out)
|
protected void writeElementContent(char[] buf, int off, int len, Writer out)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
// esccape '<', '&', ']]>'
|
// escape '<', '&', ']]>'
|
||||||
final int end = off + len;
|
final int end = off + len;
|
||||||
int pos = off;
|
int pos = off;
|
||||||
for (int i = off; i < end; i++) {
|
for (int i = off; i < end; i++) {
|
||||||
@ -1126,40 +983,18 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
// in XML 1.0 only legal character are #x9 | #xA | #xD
|
// in XML 1.0 only legal character are #x9 | #xA | #xD
|
||||||
if (ch == 9 || ch == 10 || ch == 13) {
|
if (ch == 9 || ch == 10 || ch == 13) {
|
||||||
// pass through
|
// pass through
|
||||||
|
|
||||||
// } else if(ch == 13 ) { //if(ch == '\r') {
|
|
||||||
// if(i > pos) {
|
|
||||||
// out.write(buf, pos, i - pos);
|
|
||||||
// }
|
|
||||||
// out.write("&#");
|
|
||||||
// out.write(Integer.toString(ch));
|
|
||||||
// out.write(';');
|
|
||||||
// pos = i + 1;
|
|
||||||
} else {
|
} else {
|
||||||
if (TRACE_ESCAPING)
|
if (TRACE_ESCAPING)
|
||||||
System.err.println(getClass().getName()
|
System.err.println(getClass().getName() + " DEBUG TEXT value.len=" + len + " "
|
||||||
+ " DEBUG TEXT value.len=" + len + " "
|
|
||||||
+ printable(new String(buf, off, len)));
|
+ printable(new String(buf, off, len)));
|
||||||
throw new IllegalStateException("character "
|
throw new IllegalStateException("character "
|
||||||
+ printable(ch) + " (" + Integer.toString(ch)
|
+ printable(ch) + " (" + Integer.toString(ch)
|
||||||
+ ") is not allowed in output" + getLocation());
|
+ ") is not allowed in output" + getLocation());
|
||||||
// in XML 1.1 legal are [#x1-#xD7FF]
|
|
||||||
// if(ch > 0) {
|
|
||||||
// if(i > pos) out.write(text.substring(pos, i));
|
|
||||||
// out.write("&#");
|
|
||||||
// out.write(Integer.toString(ch));
|
|
||||||
// out.write(';');
|
|
||||||
// pos = i + 1;
|
|
||||||
// } else {
|
|
||||||
// throw new IllegalStateException(
|
|
||||||
// "character zero is not allowed in XML 1.1 output"+getLocation());
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (seenBracket) {
|
if (seenBracket) {
|
||||||
seenBracketBracket = seenBracket = false;
|
seenBracketBracket = seenBracket = false;
|
||||||
}
|
}
|
||||||
// assert seenBracketBracket == seenBracket == false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (end > pos) {
|
if (end > pos) {
|
||||||
@ -1169,11 +1004,11 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
|
|
||||||
/** simple utility method -- good for debugging */
|
/** simple utility method -- good for debugging */
|
||||||
protected static final String printable(String s) {
|
protected static final String printable(String s) {
|
||||||
if (s == null)
|
if (s == null) {
|
||||||
return "null";
|
return "null";
|
||||||
|
}
|
||||||
StringBuffer retval = new StringBuffer(s.length() + 16);
|
StringBuffer retval = new StringBuffer(s.length() + 16);
|
||||||
retval.append("'");
|
retval.append("'");
|
||||||
char ch;
|
|
||||||
for (int i = 0; i < s.length(); i++) {
|
for (int i = 0; i < s.length(); i++) {
|
||||||
addPrintable(retval, s.charAt(i));
|
addPrintable(retval, s.charAt(i));
|
||||||
}
|
}
|
||||||
@ -1216,12 +1051,10 @@ public class MXSerializer implements XmlSerializer {
|
|||||||
default:
|
default:
|
||||||
if (ch < 0x20 || ch > 0x7e) {
|
if (ch < 0x20 || ch > 0x7e) {
|
||||||
final String ss = "0000" + Integer.toString(ch, 16);
|
final String ss = "0000" + Integer.toString(ch, 16);
|
||||||
retval.append("\\u"
|
retval.append("\\u" + ss.substring(ss.length() - 4));
|
||||||
+ ss.substring(ss.length() - 4, ss.length()));
|
|
||||||
} else {
|
} else {
|
||||||
retval.append(ch);
|
retval.append(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user