ToStreampublic abstract class ToStream extends SerializerBase This abstract class is a base class for other stream
serializers (xml, html, text ...) that write output to a stream. |
Fields Summary |
---|
private static final String | COMMENT_BEGIN | private static final String | COMMENT_END | protected BoolStack | m_disableOutputEscapingStatesStack to keep track of disabling output escaping. | boolean | m_triedToGetConverterBoolean that tells if we already tried to get the converter. | Method | m_canConvertMethMethod reference to the sun.io.CharToByteConverter#canConvert method
for this encoding. Invalid if m_charToByteConverter is null. | Object | m_charToByteConverterOpaque reference to the sun.io.CharToByteConverter for this
encoding. | protected BoolStack | m_preservesStack to keep track of whether or not we need to
preserve whitespace.
Used to push/pop values used for the field m_ispreserve, but
m_ispreserve is only relevant if m_doIndent is true.
If m_doIndent is false this field has no impact. | protected boolean | m_ispreserveState flag to tell if preservation of whitespace
is important.
Used only in shouldIndent() but only if m_doIndent is true.
If m_doIndent is false this flag has no impact. | protected boolean | m_isprevtextState flag that tells if the previous node processed
was text, so we can tell if we should preserve whitespace.
Used in endDocument() and shouldIndent() but
only if m_doIndent is true.
If m_doIndent is false this flag has no impact. | protected int | m_maxCharacterThe maximum character size before we have to resort
to escaping. | protected final char[] | m_lineSepThe system line separator for writing out line breaks. | protected boolean | m_lineSepUseTrue if the the system line separator is to be used. | protected final int | m_lineSepLenThe length of the line seperator, since the write is done
one character at a time. | protected CharInfo | m_charInfoMap that tells which characters should have special treatment, and it
provides character to entity name lookup. | boolean | m_shouldFlushTrue if we control the buffer, and we should flush the output on endDocument. | protected boolean | m_spaceBeforeCloseAdd space before '/>' for XHTML. | boolean | m_startNewLineFlag to signal that a newline should be added.
Used only in indent() which is called only if m_doIndent is true.
If m_doIndent is false this flag has no impact. | protected boolean | m_inDoctypeTells if we're in an internal document type subset. | boolean | m_isUTF8Flag to quickly tell if the encoding is UTF8. | protected Properties | m_formatThe xsl:output properties. | protected boolean | m_cdataStartCalledremembers if we are in between the startCDATA() and endCDATA() callbacks | private boolean | m_escapingTaken from XSLTC |
Constructors Summary |
---|
public ToStream()Default constructor
|
Methods Summary |
---|
protected int | accumDefaultEntity(java.io.Writer writer, char ch, int i, char[] chars, int len, boolean fromTextNode, boolean escLF)Handle one of the default entities, return false if it
is not a default entity.
if (!escLF && CharInfo.S_LINEFEED == ch)
{
writer.write(m_lineSep, 0, m_lineSepLen);
}
else
{
// if this is text node character and a special one of those,
// or if this is a character from attribute value and a special one of those
if ((fromTextNode && m_charInfo.isSpecialTextChar(ch)) || (!fromTextNode && m_charInfo.isSpecialAttrChar(ch)))
{
String entityRef = m_charInfo.getEntityNameForChar(ch);
if (null != entityRef)
{
writer.write('&");
writer.write(entityRef);
writer.write(';");
}
else
return i;
}
else
return i;
}
return i + 1;
| protected int | accumDefaultEscape(java.io.Writer writer, char ch, int i, char[] chars, int len, boolean fromTextNode, boolean escLF)Escape and writer.write a character.
int pos = accumDefaultEntity(writer, ch, i, chars, len, fromTextNode, escLF);
if (i == pos)
{
if (0xd800 <= ch && ch < 0xdc00)
{
// UTF-16 surrogate
int next;
if (i + 1 >= len)
{
throw new IOException(
XMLMessages.createXMLMessage(
XMLErrorResources.ER_INVALID_UTF16_SURROGATE,
new Object[] { Integer.toHexString(ch)}));
//"Invalid UTF-16 surrogate detected: "
//+Integer.toHexString(ch)+ " ?");
}
else
{
next = chars[++i];
if (!(0xdc00 <= next && next < 0xe000))
throw new IOException(
XMLMessages.createXMLMessage(
XMLErrorResources
.ER_INVALID_UTF16_SURROGATE,
new Object[] {
Integer.toHexString(ch)
+ " "
+ Integer.toHexString(next)}));
//"Invalid UTF-16 surrogate detected: "
//+Integer.toHexString(ch)+" "+Integer.toHexString(next));
next = ((ch - 0xd800) << 10) + next - 0xdc00 + 0x00010000;
}
writer.write("");
writer.write(Integer.toString(next));
writer.write(';");
pos += 2; // count the two characters that went into writing out this entity
}
else
{
if (!escapingNotNeeded(ch) ||
( (fromTextNode && m_charInfo.isSpecialTextChar(ch))
|| (!fromTextNode && m_charInfo.isSpecialAttrChar(ch))))
{
writer.write("");
writer.write(Integer.toString(ch));
writer.write(';");
}
else
{
writer.write(ch);
}
pos++; // count the single character that was processed
}
}
return pos;
| public void | addAttributeAlways(java.lang.String uri, java.lang.String localName, java.lang.String rawName, java.lang.String type, java.lang.String value)Adds the given attribute to the set of attributes, even if there is
nocurrently open element. This is useful if a SAX startPrefixMapping()
should need to add an attribute before the element name is seen.
This method is a copy of its super classes method, except that some
tracing of events is done. This is so the tracing is only done for
stream serializers, not for SAX ones.
int index;
index = m_attributes.getIndex(rawName);
if (index >= 0)
{
String old_value = null;
if (m_tracer != null)
{
old_value = m_attributes.getValue(index);
if (value.equals(old_value))
old_value = null;
}
/* We've seen the attribute before.
* We may have a null uri or localName, but all we really
* want to re-set is the value anyway.
*/
m_attributes.setValue(index, value);
if (old_value != null)
firePseudoAttributes();
}
else
{
// the attribute doesn't exist yet, create it
m_attributes.addAttribute(uri, localName, rawName, type, value);
if (m_tracer != null)
firePseudoAttributes();
}
| private void | addCdataSectionElement(java.lang.String URI_and_localName, java.util.Vector v)Adds a URI/LocalName pair of strings to the list.
StringTokenizer tokenizer =
new StringTokenizer(URI_and_localName, "{}", false);
QName qname;
String s1 = tokenizer.nextToken();
String s2 = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;
if (null == s2)
{
// add null URI and the local name
v.addElement(null);
v.addElement(s1);
}
else
{
// add URI, then local name
v.addElement(s1);
v.addElement(s2);
}
| public void | attributeDecl(java.lang.String eName, java.lang.String aName, java.lang.String type, java.lang.String valueDefault, java.lang.String value)Report an attribute type declaration.
Only the effective (first) declaration for an attribute will
be reported. The type will be one of the strings "CDATA",
"ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY",
"ENTITIES", or "NOTATION", or a parenthesized token group with
the separator "|" and all whitespace removed.
// Do not inline external DTD
if (m_inExternalDTD)
return;
try
{
final java.io.Writer writer = m_writer;
if (m_needToOutputDocTypeDecl)
{
outputDocTypeDecl(m_elemContext.m_elementName, false);
m_needToOutputDocTypeDecl = false;
}
if (m_inDoctype)
{
writer.write(" [");
writer.write(m_lineSep, 0, m_lineSepLen);
m_inDoctype = false;
}
writer.write("<!ATTLIST ");
writer.write(eName);
writer.write(' ");
writer.write(aName);
writer.write(' ");
writer.write(type);
if (valueDefault != null)
{
writer.write(' ");
writer.write(valueDefault);
}
//writer.write(" ");
//writer.write(value);
writer.write('>");
writer.write(m_lineSep, 0, m_lineSepLen);
}
catch (IOException e)
{
throw new SAXException(e);
}
| protected void | cdata(char[] ch, int start, int length)Receive notification of cdata.
The Parser will call this method to report each chunk of
character data. SAX parsers may return all contiguous character
data in a single chunk, or they may split it into several
chunks; however, all of the characters in any single event
must come from the same external entity, so that the Locator
provides useful information.
The application must not attempt to read from the array
outside of the specified range.
Note that some parsers will report whitespace using the
ignorableWhitespace() method rather than this one (validating
parsers must do so).
try
{
final int old_start = start;
if (m_elemContext.m_startTagOpen)
{
closeStartTag();
m_elemContext.m_startTagOpen = false;
}
m_ispreserve = true;
if (shouldIndent())
indent();
boolean writeCDataBrackets =
(((length >= 1) && escapingNotNeeded(ch[start])));
/* Write out the CDATA opening delimiter only if
* we are supposed to, and if we are not already in
* the middle of a CDATA section
*/
if (writeCDataBrackets && !m_cdataTagOpen)
{
m_writer.write(CDATA_DELIMITER_OPEN);
m_cdataTagOpen = true;
}
// writer.write(ch, start, length);
if (isEscapingDisabled())
{
charactersRaw(ch, start, length);
}
else
writeNormalizedChars(ch, start, length, true, m_lineSepUse);
/* used to always write out CDATA closing delimiter here,
* but now we delay, so that we can merge CDATA sections on output.
* need to write closing delimiter later
*/
if (writeCDataBrackets)
{
/* if the CDATA section ends with ] don't leave it open
* as there is a chance that an adjacent CDATA sections
* starts with ]>.
* We don't want to merge ]] with > , or ] with ]>
*/
if (ch[start + length - 1] == ']")
closeCDATA();
}
// time to fire off CDATA event
if (m_tracer != null)
super.fireCDATAEvent(ch, old_start, length);
}
catch (IOException ioe)
{
throw new org.xml.sax.SAXException(
XMLMessages.createXMLMessage(
XMLErrorResources.ER_OIERROR,
null),
ioe);
//"IO error", ioe);
}
| public void | characters(char[] chars, int start, int length)Receive notification of character data.
The Parser will call this method to report each chunk of
character data. SAX parsers may return all contiguous character
data in a single chunk, or they may split it into several
chunks; however, all of the characters in any single event
must come from the same external entity, so that the Locator
provides useful information.
The application must not attempt to read from the array
outside of the specified range.
Note that some parsers will report whitespace using the
ignorableWhitespace() method rather than this one (validating
parsers must do so).
if (m_elemContext.m_startTagOpen)
{
closeStartTag();
m_elemContext.m_startTagOpen = false;
}
else if (m_needToCallStartDocument)
{
startDocumentInternal();
}
if (m_cdataStartCalled || m_elemContext.m_isCdataSection)
{
/* either due to startCDATA() being called or due to
* cdata-section-elements atribute, we need this as cdata
*/
cdata(chars, start, length);
return;
}
if (m_cdataTagOpen)
closeCDATA();
// the check with _escaping is a bit of a hack for XLSTC
if (m_disableOutputEscapingStates.peekOrFalse() || (!m_escaping))
{
charactersRaw(chars, start, length);
// time to fire off characters generation event
if (m_tracer != null)
super.fireCharEvent(chars, start, length);
return;
}
if (m_elemContext.m_startTagOpen)
{
closeStartTag();
m_elemContext.m_startTagOpen = false;
}
try
{
int i;
char ch1;
int startClean;
// skip any leading whitspace
// don't go off the end and use a hand inlined version
// of isWhitespace(ch)
final int end = start + length;
int lastDirty = start - 1; // last character that needed processing
for (i = start;
((i < end)
&& ((ch1 = chars[i]) == 0x20
|| (ch1 == 0xA && m_lineSepUse)
|| ch1 == 0xD
|| ch1 == 0x09));
i++)
{
/*
* We are processing leading whitespace, but are doing the same
* processing for dirty characters here as for non-whitespace.
*
*/
if (!m_charInfo.isTextASCIIClean(ch1))
{
lastDirty = processDirty(chars,end, i,ch1, lastDirty, true);
i = lastDirty;
}
}
/* If there is some non-whitespace, mark that we may need
* to preserve this. This is only important if we have indentation on.
*/
if (i < end)
m_ispreserve = true;
// int lengthClean; // number of clean characters in a row
// final boolean[] isAsciiClean = m_charInfo.getASCIIClean();
// we've skipped the leading whitespace, now deal with the rest
for (; i < end; i++)
{
{
// A tight loop to skip over common clean chars
// This tight loop makes it easier for the JIT
// to optimize.
char ch2;
while (i<end
&& ((ch2 = chars[i])<127)
&& m_charInfo.isTextASCIIClean(ch2))
i++;
if (i == end)
break;
}
final char ch = chars[i];
if (
(escapingNotNeeded(ch) && (!m_charInfo.isSpecialTextChar(ch)))
|| ('"" == ch))
{
; // a character needing no special processing
}
else
{
lastDirty = processDirty(chars,end, i, ch, lastDirty, true);
i = lastDirty;
}
}
// we've reached the end. Any clean characters at the
// end of the array than need to be written out?
startClean = lastDirty + 1;
if (i > startClean)
{
int lengthClean = i - startClean;
m_writer.write(chars, startClean, lengthClean);
}
// For indentation purposes, mark that we've just writen text out
m_isprevtext = true;
}
catch (IOException e)
{
throw new SAXException(e);
}
// time to fire off characters generation event
if (m_tracer != null)
super.fireCharEvent(chars, start, length);
| public void | characters(java.lang.String s)Receive notification of character data.
final int length = s.length();
if (length > m_charsBuff.length)
{
m_charsBuff = new char[length * 2 + 1];
}
s.getChars(0, length, m_charsBuff, 0);
characters(m_charsBuff, 0, length);
| protected void | charactersRaw(char[] ch, int start, int length)If available, when the disable-output-escaping attribute is used,
output raw text without escaping.
if (m_inEntityRef)
return;
try
{
if (m_elemContext.m_startTagOpen)
{
closeStartTag();
m_elemContext.m_startTagOpen = false;
}
m_ispreserve = true;
m_writer.write(ch, start, length);
}
catch (IOException e)
{
throw new SAXException(e);
}
| protected void | closeCDATA()This helper method to writes out "]]>" when closing a CDATA section.
try
{
m_writer.write(CDATA_DELIMITER_CLOSE);
// write out a CDATA section closing "]]>"
m_cdataTagOpen = false; // Remember that we have done so.
}
catch (IOException e)
{
throw new SAXException(e);
}
| protected void | closeStartTag()For the enclosing elements starting tag write out
out any attributes followed by ">"
if (m_elemContext.m_startTagOpen)
{
try
{
if (m_tracer != null)
super.fireStartElem(m_elemContext.m_elementName);
int nAttrs = m_attributes.getLength();
if (nAttrs > 0)
{
processAttributes(m_writer, nAttrs);
// clear attributes object for re-use with next element
m_attributes.clear();
}
m_writer.write('>");
}
catch (IOException e)
{
throw new SAXException(e);
}
/* whether Xalan or XSLTC, we have the prefix mappings now, so
* lets determine if the current element is specified in the cdata-
* section-elements list.
*/
if (m_cdataSectionElements != null)
m_elemContext.m_isCdataSection = isCdataSection();
if (m_doIndent)
{
m_isprevtext = false;
m_preserves.push(m_ispreserve);
}
}
| public void | comment(char[] ch, int start, int length)Receive notification of an XML comment anywhere in the document. This
callback will be used for comments inside or outside the document
element, including comments in the external DTD subset (if read).
int start_old = start;
if (m_inEntityRef)
return;
if (m_elemContext.m_startTagOpen)
{
closeStartTag();
m_elemContext.m_startTagOpen = false;
}
else if (m_needToCallStartDocument)
{
startDocumentInternal();
m_needToCallStartDocument = false;
}
try
{
if (shouldIndent())
indent();
final int limit = start + length;
boolean wasDash = false;
if (m_cdataTagOpen)
closeCDATA();
final java.io.Writer writer = m_writer;
writer.write(COMMENT_BEGIN);
// Detect occurrences of two consecutive dashes, handle as necessary.
for (int i = start; i < limit; i++)
{
if (wasDash && ch[i] == '-")
{
writer.write(ch, start, i - start);
writer.write(" -");
start = i + 1;
}
wasDash = (ch[i] == '-");
}
// if we have some chars in the comment
if (length > 0)
{
// Output the remaining characters (if any)
final int remainingChars = (limit - start);
if (remainingChars > 0)
writer.write(ch, start, remainingChars);
// Protect comment end from a single trailing dash
if (ch[limit - 1] == '-")
writer.write(' ");
}
writer.write(COMMENT_END);
}
catch (IOException e)
{
throw new SAXException(e);
}
m_startNewLine = true;
// time to generate comment event
if (m_tracer != null)
super.fireCommentEvent(ch, start_old,length);
| public void | elementDecl(java.lang.String name, java.lang.String model)Report an element type declaration.
The content model will consist of the string "EMPTY", the
string "ANY", or a parenthesised group, optionally followed
by an occurrence indicator. The model will be normalized so
that all whitespace is removed,and will include the enclosing
parentheses.
// Do not inline external DTD
if (m_inExternalDTD)
return;
try
{
final java.io.Writer writer = m_writer;
if (m_needToOutputDocTypeDecl)
{
outputDocTypeDecl(m_elemContext.m_elementName, false);
m_needToOutputDocTypeDecl = false;
}
if (m_inDoctype)
{
writer.write(" [");
writer.write(m_lineSep, 0, m_lineSepLen);
m_inDoctype = false;
}
writer.write("<!ELEMENT ");
writer.write(name);
writer.write(' ");
writer.write(model);
writer.write('>");
writer.write(m_lineSep, 0, m_lineSepLen);
}
catch (IOException e)
{
throw new SAXException(e);
}
| public void | endCDATA()Report the end of a CDATA section.
if (m_cdataTagOpen)
closeCDATA();
m_cdataStartCalled = false;
| public void | endDTD()Report the end of DTD declarations.
try
{
final java.io.Writer writer = m_writer;
if (!m_inDoctype){
writer.write("]>");
writer.write(m_lineSep, 0, m_lineSepLen);
}
}
catch (IOException e)
{
throw new SAXException(e);
}
| public void | endElement(java.lang.String namespaceURI, java.lang.String localName, java.lang.String name)Receive notification of the end of an element.
if (m_inEntityRef)
return;
// namespaces declared at the current depth are no longer valid
// so get rid of them
m_prefixMap.popNamespaces(m_elemContext.m_currentElemDepth, null);
try
{
final java.io.Writer writer = m_writer;
if (m_elemContext.m_startTagOpen)
{
if (m_tracer != null)
super.fireStartElem(m_elemContext.m_elementName);
int nAttrs = m_attributes.getLength();
if (nAttrs > 0)
{
processAttributes(m_writer, nAttrs);
// clear attributes object for re-use with next element
m_attributes.clear();
}
if (m_spaceBeforeClose)
writer.write(" />");
else
writer.write("/>");
/* don't need to pop cdataSectionState because
* this element ended so quickly that we didn't get
* to push the state.
*/
}
else
{
if (m_cdataTagOpen)
closeCDATA();
if (shouldIndent())
indent(m_elemContext.m_currentElemDepth - 1);
writer.write('<");
writer.write('/");
writer.write(name);
writer.write('>");
}
}
catch (IOException e)
{
throw new SAXException(e);
}
if (!m_elemContext.m_startTagOpen && m_doIndent)
{
m_ispreserve = m_preserves.isEmpty() ? false : m_preserves.pop();
}
m_isprevtext = false;
// fire off the end element event
if (m_tracer != null)
super.fireEndElem(name);
m_elemContext = m_elemContext.m_prev;
| public void | endElement(java.lang.String name)Receive notification of the end of an element.
endElement(null, null, name);
| public void | endNonEscaping()Ends an un-escaping section.
m_disableOutputEscapingStates.pop();
| public void | endPrefixMapping(java.lang.String prefix)End the scope of a prefix-URI Namespace mapping. // do nothing
| protected java.lang.String | ensureAttributesNamespaceIsDeclared(java.lang.String ns, java.lang.String localName, java.lang.String rawName)Makes sure that the namespace URI for the given qualified attribute name
is declared.
if (ns != null && ns.length() > 0)
{
// extract the prefix in front of the raw name
int index = 0;
String prefixFromRawName =
(index = rawName.indexOf(":")) < 0
? ""
: rawName.substring(0, index);
if (index > 0)
{
// we have a prefix, lets see if it maps to a namespace
String uri = m_prefixMap.lookupNamespace(prefixFromRawName);
if (uri != null && uri.equals(ns))
{
// the prefix in the raw name is already maps to the given namespace uri
// so we don't need to do anything
return null;
}
else
{
// The uri does not map to the prefix in the raw name,
// so lets make the mapping.
this.startPrefixMapping(prefixFromRawName, ns, false);
this.addAttribute(
"http://www.w3.org/2000/xmlns/",
prefixFromRawName,
"xmlns:" + prefixFromRawName,
"CDATA",
ns);
return prefixFromRawName;
}
}
else
{
// we don't have a prefix in the raw name.
// Does the URI map to a prefix already?
String prefix = m_prefixMap.lookupPrefix(ns);
if (prefix == null)
{
// uri is not associated with a prefix,
// so lets generate a new prefix to use
prefix = m_prefixMap.generateNextPrefix();
this.startPrefixMapping(prefix, ns, false);
this.addAttribute(
"http://www.w3.org/2000/xmlns/",
prefix,
"xmlns:" + prefix,
"CDATA",
ns);
}
return prefix;
}
}
return null;
| void | ensurePrefixIsDeclared(java.lang.String ns, java.lang.String rawName)
if (ns != null && ns.length() > 0)
{
int index;
String prefix =
(index = rawName.indexOf(":")) < 0
? ""
: rawName.substring(0, index);
if (null != prefix)
{
String foundURI = m_prefixMap.lookupNamespace(prefix);
if ((null == foundURI) || !foundURI.equals(ns))
{
this.startPrefixMapping(prefix, ns);
// Bugzilla1133: Generate attribute as well as namespace event.
// SAX does expect both.
this.addAttributeAlways(
"http://www.w3.org/2000/xmlns/",
prefix,
"xmlns" + (prefix.length() == 0 ? "" : ":") + prefix,
"CDATA",
ns);
}
}
}
| protected boolean | escapingNotNeeded(char ch)Tell if this character can be written without escaping.
if (ch < 127)
{
if (ch >= 0x20 || (0x0A == ch || 0x0D == ch || 0x09 == ch))
return true;
else
return false;
}
if (null == m_charToByteConverter && false == m_triedToGetConverter)
{
m_triedToGetConverter = true;
try
{
m_charToByteConverter =
Encodings.getCharToByteConverter(getEncoding());
if (null != m_charToByteConverter)
{
Class argsTypes[] = new Class[1];
argsTypes[0] = Character.TYPE;
Class convClass = m_charToByteConverter.getClass();
m_canConvertMeth =
convClass.getMethod("canConvert", argsTypes);
}
}
catch (Exception e)
{
// This is just an assert: no action at the moment.
System.err.println("Warning: " + e.getMessage());
}
}
if (null != m_charToByteConverter)
{
try
{
Object args[] = new Object[1];
args[0] = new Character(ch);
Boolean bool =
(Boolean) m_canConvertMeth.invoke(
m_charToByteConverter,
args);
return bool.booleanValue()
? !Character.isISOControl(ch)
: false;
}
catch (java.lang.reflect.InvocationTargetException ite)
{
// This is just an assert: no action at the moment.
System.err.println(
"Warning: InvocationTargetException in canConvert!");
}
catch (java.lang.IllegalAccessException iae)
{
// This is just an assert: no action at the moment.
System.err.println(
"Warning: IllegalAccessException in canConvert!");
}
}
// fallback!
return (ch <= m_maxCharacter);
| public void | externalEntityDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId)Report a parsed external entity declaration.
Only the effective (first) declaration for each entity
will be reported.
| protected void | firePseudoAttributes()To fire off the pseudo characters of attributes, as they currently
exist. This method should be called everytime an attribute is added,
or when an attribute value is changed, or an element is created.
if (m_tracer != null)
{
try
{
// flush out the "<elemName" if not already flushed
m_writer.flush();
// make a StringBuffer to write the name="value" pairs to.
StringBuffer sb = new StringBuffer();
int nAttrs = m_attributes.getLength();
if (nAttrs > 0)
{
// make a writer that internally appends to the same
// StringBuffer
java.io.Writer writer =
new ToStream.WritertoStringBuffer(sb);
processAttributes(writer, nAttrs);
// Don't clear the attributes!
// We only want to see what would be written out
// at this point, we don't want to loose them.
}
sb.append('>"); // the potential > after the attributes.
// convert the StringBuffer to a char array and
// emit the trace event that these characters "might"
// be written
char ch[] = sb.toString().toCharArray();
m_tracer.fireGenerateEvent(
SerializerTrace.EVENTTYPE_OUTPUT_PSEUDO_CHARACTERS,
ch,
0,
ch.length);
}
catch (IOException ioe)
{
// ignore ?
}
catch (SAXException se)
{
// ignore ?
}
}
| public void | flushPending()This method flushes any pending events, which can be startDocument()
closing the opening tag of an element, or closing an open CDATA section.
if (m_needToCallStartDocument)
{
startDocumentInternal();
m_needToCallStartDocument = false;
}
if (m_elemContext.m_startTagOpen)
{
closeStartTag();
m_elemContext.m_startTagOpen = false;
}
if (m_cdataTagOpen)
{
closeCDATA();
m_cdataTagOpen = false;
}
| protected final void | flushWriter()Flush the formatter's result stream.
final java.io.Writer writer = m_writer;
if (null != writer)
{
try
{
if (writer instanceof WriterToUTF8Buffered)
{
if (m_shouldFlush)
((WriterToUTF8Buffered) writer).flush();
else
((WriterToUTF8Buffered) writer).flushBuffer();
}
if (writer instanceof WriterToASCI)
{
if (m_shouldFlush)
writer.flush();
}
else
{
// Flush always.
// Not a great thing if the writer was created
// by this class, but don't have a choice.
writer.flush();
}
}
catch (IOException ioe)
{
throw new org.xml.sax.SAXException(ioe);
}
}
| public int | getIndentAmount()Returns the m_indentAmount.
return m_indentAmount;
| public java.util.Properties | getOutputFormat()Returns the output format for this serializer.
return m_format;
| public java.io.OutputStream | getOutputStream()Get the output stream where the events will be serialized to.
if (m_writer instanceof WriterToUTF8Buffered)
return ((WriterToUTF8Buffered) m_writer).getOutputStream();
if (m_writer instanceof WriterToASCI)
return ((WriterToASCI) m_writer).getOutputStream();
else
return null;
| int | getURF16SurrogateValue(char c, char[] ch, int i, int end)Once a surrogate has been detected, get the pair as a single integer
value.
int next;
if (i + 1 >= end)
{
throw new IOException(
XMLMessages.createXMLMessage(
XMLErrorResources.ER_INVALID_UTF16_SURROGATE,
new Object[] { Integer.toHexString((int) c)}));
//"Invalid UTF-16 surrogate detected: "
//+Integer.toHexString((int)c)+ " ?");
}
else
{
next = ch[++i];
if (!(0xdc00 <= next && next < 0xe000))
throw new IOException(
XMLMessages.createXMLMessage(
XMLErrorResources.ER_INVALID_UTF16_SURROGATE,
new Object[] {
Integer.toHexString((int) c)
+ " "
+ Integer.toHexString(next)}));
//"Invalid UTF-16 surrogate detected: "
//+Integer.toHexString((int)c)+" "+Integer.toHexString(next));
next = ((c - 0xd800) << 10) + next - 0xdc00 + 0x00010000;
}
return next;
| public java.io.Writer | getWriter()Get the character stream where the events will be serialized to.
return m_writer;
| public void | ignorableWhitespace(char[] ch, int start, int length)Receive notification of ignorable whitespace in element content.
Not sure how to get this invoked quite yet.
if (0 == length)
return;
characters(ch, start, length);
| protected void | indent(int depth)Might print a newline character and the indentation amount
of the given depth.
if (m_startNewLine)
outputLineSep();
/* For m_indentAmount > 0 this extra test might be slower
* but Xalan's default value is 0, so this extra test
* will run faster in that situation.
*/
if (m_indentAmount > 0)
printSpace(depth * m_indentAmount);
| protected void | indent()Indent at the current element nesting depth.
indent(m_elemContext.m_currentElemDepth);
| private synchronized void | init(java.io.Writer writer, java.util.Properties format, boolean defaultProperties, boolean shouldFlush)Initialize the serializer with the specified writer and output format.
Must be called before calling any of the serialize methods.
m_shouldFlush = shouldFlush;
// if we are tracing events we need to trace what
// characters are written to the output writer.
if (m_tracer != null
&& !(writer instanceof SerializerTraceWriter) )
m_writer = new SerializerTraceWriter(writer, m_tracer);
else
m_writer = writer;
m_format = format;
// m_cdataSectionNames =
// OutputProperties.getQNameProperties(
// OutputKeys.CDATA_SECTION_ELEMENTS,
// format);
setCdataSectionElements(OutputKeys.CDATA_SECTION_ELEMENTS, format);
setIndentAmount(
OutputPropertyUtils.getIntProperty(
OutputPropertiesFactory.S_KEY_INDENT_AMOUNT,
format));
setIndent(
OutputPropertyUtils.getBooleanProperty(OutputKeys.INDENT, format));
boolean shouldNotWriteXMLHeader =
OutputPropertyUtils.getBooleanProperty(
OutputKeys.OMIT_XML_DECLARATION,
format);
setOmitXMLDeclaration(shouldNotWriteXMLHeader);
setDoctypeSystem(format.getProperty(OutputKeys.DOCTYPE_SYSTEM));
String doctypePublic = format.getProperty(OutputKeys.DOCTYPE_PUBLIC);
setDoctypePublic(doctypePublic);
// if standalone was explicitly specified
if (format.get(OutputKeys.STANDALONE) != null)
{
String val = format.getProperty(OutputKeys.STANDALONE);
if (defaultProperties)
setStandaloneInternal(val);
else
setStandalone(val);
}
setMediaType(format.getProperty(OutputKeys.MEDIA_TYPE));
if (null != doctypePublic)
{
if (doctypePublic.startsWith("-//W3C//DTD XHTML"))
m_spaceBeforeClose = true;
}
// initCharsMap();
String encoding = getEncoding();
if (null == encoding)
{
encoding =
Encodings.getMimeEncoding(
format.getProperty(OutputKeys.ENCODING));
setEncoding(encoding);
}
m_isUTF8 = encoding.equals(Encodings.DEFAULT_MIME_ENCODING);
m_maxCharacter = Encodings.getLastPrintable(encoding);
// Access this only from the Hashtable level... we don't want to
// get default properties.
String entitiesFileName =
(String) format.get(OutputPropertiesFactory.S_KEY_ENTITIES);
if (null != entitiesFileName)
{
String method =
(String) format.get(OutputKeys.METHOD);
m_charInfo = CharInfo.getCharInfo(entitiesFileName, method);
}
| private synchronized void | init(java.io.Writer writer, java.util.Properties format)Initialize the serializer with the specified writer and output format.
Must be called before calling any of the serialize methods.
init(writer, format, false, false);
| protected synchronized void | init(java.io.OutputStream output, java.util.Properties format, boolean defaultProperties)Initialize the serializer with the specified output stream and output
format. Must be called before calling any of the serialize methods.
String encoding = getEncoding();
if (encoding == null)
{
// if not already set then get it from the properties
encoding =
Encodings.getMimeEncoding(
format.getProperty(OutputKeys.ENCODING));
setEncoding(encoding);
}
if (encoding.equalsIgnoreCase("UTF-8"))
{
m_isUTF8 = true;
// if (output instanceof java.io.BufferedOutputStream)
// {
// init(new WriterToUTF8(output), format, defaultProperties, true);
// }
// else if (output instanceof java.io.FileOutputStream)
// {
// init(new WriterToUTF8Buffered(output), format, defaultProperties, true);
// }
// else
// {
// // Not sure what to do in this case. I'm going to be conservative
// // and not buffer.
// init(new WriterToUTF8(output), format, defaultProperties, true);
// }
init(
new WriterToUTF8Buffered(output),
format,
defaultProperties,
true);
}
else if (
encoding.equals("WINDOWS-1250")
|| encoding.equals("US-ASCII")
|| encoding.equals("ASCII"))
{
init(new WriterToASCI(output), format, defaultProperties, true);
}
else
{
Writer osw;
try
{
osw = Encodings.getWriter(output, encoding);
}
catch (UnsupportedEncodingException uee)
{
System.out.println(
"Warning: encoding \""
+ encoding
+ "\" not supported"
+ ", using "
+ Encodings.DEFAULT_MIME_ENCODING);
encoding = Encodings.DEFAULT_MIME_ENCODING;
setEncoding(encoding);
osw = Encodings.getWriter(output, encoding);
}
m_maxCharacter = Encodings.getLastPrintable(encoding);
init(osw, format, defaultProperties, true);
}
| public void | internalEntityDecl(java.lang.String name, java.lang.String value)Report an internal entity declaration.
Only the effective (first) declaration for each entity
will be reported.
// Do not inline external DTD
if (m_inExternalDTD)
return;
try
{
if (m_needToOutputDocTypeDecl)
{
outputDocTypeDecl(m_elemContext.m_elementName, false);
m_needToOutputDocTypeDecl = false;
}
if (m_inDoctype)
{
final java.io.Writer writer = m_writer;
writer.write(" [");
writer.write(m_lineSep, 0, m_lineSepLen);
m_inDoctype = false;
}
outputEntityDecl(name, value);
}
catch (IOException e)
{
throw new SAXException(e);
}
| private boolean | isEscapingDisabled()Tell if the character escaping should be disabled for the current state.
return m_disableOutputEscapingStates.peekOrFalse();
| static final boolean | isUTF16Surrogate(char c)Return true if the character is the high member of a surrogate pair.
NEEDSDOC @param c
NEEDSDOC ($objectName$) @return
return (c & 0xFC00) == 0xD800;
| void | outputDocTypeDecl(java.lang.String name, boolean closeDecl)Output the doc type declaration.
if (m_cdataTagOpen)
closeCDATA();
try
{
final java.io.Writer writer = m_writer;
writer.write("<!DOCTYPE ");
writer.write(name);
String doctypePublic = getDoctypePublic();
if (null != doctypePublic)
{
writer.write(" PUBLIC \"");
writer.write(doctypePublic);
writer.write('\"");
}
String doctypeSystem = getDoctypeSystem();
if (null != doctypeSystem)
{
if (null == doctypePublic)
writer.write(" SYSTEM \"");
else
writer.write(" \"");
writer.write(doctypeSystem);
if (closeDecl)
{
writer.write("\">");
writer.write(m_lineSep, 0, m_lineSepLen);
closeDecl = false; // done closing
}
else
writer.write('\"");
}
boolean dothis = false;
if (dothis)
{
// at one point this code seemed right,
// but not anymore - bjm
if (closeDecl)
{
writer.write('>");
writer.write(m_lineSep, 0, m_lineSepLen);
}
}
}
catch (IOException e)
{
throw new SAXException(e);
}
| void | outputEntityDecl(java.lang.String name, java.lang.String value)Output the doc type declaration.
final java.io.Writer writer = m_writer;
writer.write("<!ENTITY ");
writer.write(name);
writer.write(" \"");
writer.write(value);
writer.write("\">");
writer.write(m_lineSep, 0, m_lineSepLen);
| protected final void | outputLineSep()Output a system-dependent line break.
m_writer.write(m_lineSep, 0, m_lineSepLen);
| private void | printSpace(int n)Prints n spaces.
final java.io.Writer writer = m_writer;
for (int i = 0; i < n; i++)
{
writer.write(' ");
}
| public void | processAttributes(java.io.Writer writer, int nAttrs)Process the attributes, which means to write out the currently
collected attributes to the writer. The attributes are not
cleared by this method
/* real SAX attributes are not passed in, so process the
* attributes that were collected after the startElement call.
* _attribVector is a "cheap" list for Stream serializer output
* accumulated over a series of calls to attribute(name,value)
*/
String encoding = getEncoding();
for (int i = 0; i < nAttrs; i++)
{
// elementAt is JDK 1.1.8
final String name = m_attributes.getQName(i);
final String value = m_attributes.getValue(i);
writer.write(' ");
writer.write(name);
writer.write("=\"");
writeAttrString(writer, value, encoding);
writer.write('\"");
}
| private int | processDirty(char[] chars, int end, int i, char ch, int lastDirty, boolean fromTextNode)Process a dirty character and any preeceding clean characters
that were not yet processed.
int startClean = lastDirty + 1;
// if we have some clean characters accumulated
// process them before the dirty one.
if (i > startClean)
{
int lengthClean = i - startClean;
m_writer.write(chars, startClean, lengthClean);
}
// process the "dirty" character
if (CharInfo.S_LINEFEED == ch && fromTextNode)
{
m_writer.write(m_lineSep, 0, m_lineSepLen);
}
else
{
startClean =
accumDefaultEscape(
m_writer,
(char)ch,
i,
chars,
end,
fromTextNode,
false);
i = startClean - 1;
}
// Return the index of the last character that we just processed
// which is a dirty character.
return i;
| public boolean | reset()Try's to reset the super class and reset this class for
re-use, so that you don't need to create a new serializer
(mostly for performance reasons).
boolean wasReset = false;
if (super.reset())
{
resetToStream();
wasReset = true;
}
return wasReset;
| private void | resetToStream()Reset all of the fields owned by ToStream class
this.m_canConvertMeth = null;
this.m_cdataStartCalled = false;
/* The stream is being reset. It is one of
* ToXMLStream, ToHTMLStream ... and this type can't be changed
* so neither should m_charInfo which is associated with the
* type of Stream. Just leave m_charInfo as-is for the next re-use.
*
*/
// this.m_charInfo = null; // don't set to null
this.m_charToByteConverter = null;
this.m_disableOutputEscapingStates.clear();
this.m_escaping = true;
// Leave m_format alone for now - bjm
// this.m_format = null;
this.m_inDoctype = false;
this.m_ispreserve = false;
this.m_ispreserve = false;
this.m_isprevtext = false;
this.m_isUTF8 = false; // ?? used anywhere ??
this.m_maxCharacter = Encodings.getLastPrintable();
this.m_preserves.clear();
this.m_shouldFlush = true;
this.m_spaceBeforeClose = false;
this.m_startNewLine = false;
this.m_triedToGetConverter = false;
this.m_lineSepUse = true;
// DON'T SET THE WRITER TO NULL, IT MAY BE REUSED !!
// this.m_writer = null;
| public void | serialize(org.w3c.dom.Node node)Serializes the DOM node. Throws an exception only if an I/O
exception occured while serializing.
try
{
TreeWalker walker =
new TreeWalker(this, new com.sun.org.apache.xml.internal.utils.DOM2Helper());
walker.traverse(node);
}
catch (org.xml.sax.SAXException se)
{
throw new WrappedRuntimeException(se);
}
| private void | setCdataSectionElements(java.lang.String key, java.util.Properties props)Searches for the list of qname properties with the specified key in the
property list. If the key is not found in this property list, the default
property list, and its defaults, recursively, are then checked. The
method returns null if the property is not found.
String s = props.getProperty(key);
if (null != s)
{
// Vector of URI/LocalName pairs
Vector v = new Vector();
int l = s.length();
boolean inCurly = false;
FastStringBuffer buf = new FastStringBuffer();
// parse through string, breaking on whitespaces. I do this instead
// of a tokenizer so I can track whitespace inside of curly brackets,
// which theoretically shouldn't happen if they contain legal URLs.
for (int i = 0; i < l; i++)
{
char c = s.charAt(i);
if (Character.isWhitespace(c))
{
if (!inCurly)
{
if (buf.length() > 0)
{
addCdataSectionElement(buf.toString(), v);
buf.reset();
}
continue;
}
}
else if ('{" == c)
inCurly = true;
else if ('}" == c)
inCurly = false;
buf.append(c);
}
if (buf.length() > 0)
{
addCdataSectionElement(buf.toString(), v);
buf.reset();
}
// call the official, public method to set the collected names
setCdataSectionElements(v);
}
| public void | setCdataSectionElements(java.util.Vector URI_and_localNames)Remembers the cdata sections specified in the cdata-section-elements.
The "official way to set URI and localName pairs.
This method should be used by both Xalan and XSLTC.
m_cdataSectionElements = URI_and_localNames;
| public void | setContentHandler(org.xml.sax.ContentHandler ch)
// this method is really only useful in the ToSAXHandler classes but it is
// in the interface. If the method defined here is ever called
// we are probably in trouble.
| public void | setEncoding(java.lang.String encoding)Sets the character encoding coming from the xsl:output encoding stylesheet attribute.
super.setEncoding(encoding);
m_maxCharacter = Encodings.getLastPrintable(encoding);
return;
| public boolean | setEscaping(boolean escape)
final boolean temp = m_escaping;
m_escaping = escape;
return temp;
| public void | setIndentAmount(int m_indentAmount)Sets the m_indentAmount.
this.m_indentAmount = m_indentAmount;
| public boolean | setLineSepUse(boolean use_sytem_line_break)Set if the operating systems end-of-line line separator should
be used when serializing. If set false NL character
(decimal 10) is left alone, otherwise the new-line will be replaced on
output with the systems line separator. For example on UNIX this is
NL, while on Windows it is two characters, CR NL, where CR is the
carriage-return (decimal 13).
boolean oldValue = m_lineSepUse;
m_lineSepUse = use_sytem_line_break;
return oldValue;
| public void | setOutputFormat(java.util.Properties format)Specifies an output format for this serializer. It the
serializer has already been associated with an output format,
it will switch to the new format. This method should not be
called while the serializer is in the process of serializing
a document.
boolean shouldFlush = m_shouldFlush;
init(m_writer, format, false, false);
m_shouldFlush = shouldFlush;
| public void | setOutputStream(java.io.OutputStream output)Specifies an output stream to which the document should be
serialized. This method should not be called while the
serializer is in the process of serializing a document.
The encoding specified in the output properties is used, or
if no encoding was specified, the default for the selected
output method.
try
{
Properties format;
if (null == m_format)
format =
OutputPropertiesFactory.getDefaultMethodProperties(
Method.XML);
else
format = m_format;
init(output, format, true);
}
catch (UnsupportedEncodingException uee)
{
// Should have been warned in init, I guess...
}
| public void | setTransformer(javax.xml.transform.Transformer transformer)
super.setTransformer(transformer);
if (m_tracer != null
&& !(m_writer instanceof SerializerTraceWriter) )
m_writer = new SerializerTraceWriter(m_writer, m_tracer);
| public void | setWriter(java.io.Writer writer)Specifies a writer to which the document should be serialized.
This method should not be called while the serializer is in
the process of serializing a document.
// if we are tracing events we need to trace what
// characters are written to the output writer.
if (m_tracer != null
&& !(writer instanceof SerializerTraceWriter) )
m_writer = new SerializerTraceWriter(writer, m_tracer);
else
m_writer = writer;
| protected boolean | shouldIndent()Tell if, based on space preservation constraints and the doIndent property,
if an indent should occur.
return m_doIndent && (!m_ispreserve && !m_isprevtext);
| public void | skippedEntity(java.lang.String name)Receive notification of a skipped entity. // TODO: Should handle
| public void | startCDATA()Report the start of a CDATA section.
m_cdataStartCalled = true;
| public void | startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)Report the start of DTD declarations, if any.
Any declarations are assumed to be in the internal subset unless
otherwise indicated.
setDoctypeSystem(systemId);
setDoctypePublic(publicId);
m_elemContext.m_elementName = name;
m_inDoctype = true;
| public void | startElement(java.lang.String namespaceURI, java.lang.String localName, java.lang.String name, org.xml.sax.Attributes atts)Receive notification of the beginning of an element, although this is a
SAX method additional namespace or attribute information can occur before
or after this call, that is associated with this element.
if (m_inEntityRef)
return;
if (m_needToCallStartDocument)
{
startDocumentInternal();
m_needToCallStartDocument = false;
}
else if (m_cdataTagOpen)
closeCDATA();
try
{
if ((true == m_needToOutputDocTypeDecl)
&& (null != getDoctypeSystem()))
{
outputDocTypeDecl(name, true);
}
m_needToOutputDocTypeDecl = false;
/* before we over-write the current elementLocalName etc.
* lets close out the old one (if we still need to)
*/
if (m_elemContext.m_startTagOpen)
{
closeStartTag();
m_elemContext.m_startTagOpen = false;
}
if (namespaceURI != null)
ensurePrefixIsDeclared(namespaceURI, name);
m_ispreserve = false;
if (shouldIndent() && m_startNewLine)
{
indent();
}
m_startNewLine = true;
final java.io.Writer writer = m_writer;
writer.write('<");
writer.write(name);
}
catch (IOException e)
{
throw new SAXException(e);
}
// process the attributes now, because after this SAX call they might be gone
if (atts != null)
addAttributes(atts);
m_elemContext = m_elemContext.push(namespaceURI,localName,name);
m_isprevtext = false;
if (m_tracer != null)
firePseudoAttributes();
| public void | startElement(java.lang.String elementNamespaceURI, java.lang.String elementLocalName, java.lang.String elementName)Receive notification of the beginning of an element, additional
namespace or attribute information can occur before or after this call,
that is associated with this element.
startElement(elementNamespaceURI, elementLocalName, elementName, null);
| public void | startElement(java.lang.String elementName)
startElement(null, null, elementName, null);
| public void | startEntity(java.lang.String name)Report the beginning of an entity.
The start and end of the document entity are not reported.
The start and end of the external DTD subset are reported
using the pseudo-name "[dtd]". All other events must be
properly nested within start/end entity events.
if (name.equals("[dtd]"))
m_inExternalDTD = true;
m_inEntityRef = true;
| public void | startNonEscaping()Starts an un-escaping section. All characters printed within an un-
escaping section are printed as is, without escaping special characters
into entity references. Only XML and HTML serializers need to support
this method.
The contents of the un-escaping section will be delivered through the
regular characters event.
m_disableOutputEscapingStates.push(true);
| public void | startPrefixMapping(java.lang.String prefix, java.lang.String uri)Begin the scope of a prefix-URI Namespace mapping
just before another element is about to start.
This call will close any open tags so that the prefix mapping
will not apply to the current element, but the up comming child.
// the "true" causes the flush of any open tags
startPrefixMapping(prefix, uri, true);
| public boolean | startPrefixMapping(java.lang.String prefix, java.lang.String uri, boolean shouldFlush)Handle a prefix/uri mapping, which is associated with a startElement()
that is soon to follow. Need to close any open start tag to make
sure than any name space attributes due to this event are associated wih
the up comming element, not the current one.
/* Remember the mapping, and at what depth it was declared
* This is one greater than the current depth because these
* mappings will apply to the next depth. This is in
* consideration that startElement() will soon be called
*/
boolean pushed;
int pushDepth;
if (shouldFlush)
{
flushPending();
// the prefix mapping applies to the child element (one deeper)
pushDepth = m_elemContext.m_currentElemDepth + 1;
}
else
{
// the prefix mapping applies to the current element
pushDepth = m_elemContext.m_currentElemDepth;
}
pushed = m_prefixMap.pushNamespace(prefix, uri, pushDepth);
if (pushed)
{
/* bjm: don't know if we really needto do this. The
* callers of this object should have injected both
* startPrefixMapping and the attributes. We are
* just covering our butt here.
*/
String name;
if (EMPTYSTRING.equals(prefix))
{
name = "xmlns";
addAttributeAlways(XMLNS_URI, prefix, name, "CDATA", uri);
}
else
{
if (!EMPTYSTRING.equals(uri))
// hack for XSLTC attribset16 test
{ // that maps ns1 prefix to "" URI
name = "xmlns:" + prefix;
/* for something like xmlns:abc="w3.pretend.org"
* the uri is the value, that is why we pass it in the
* value, or 5th slot of addAttributeAlways()
*/
addAttributeAlways(XMLNS_URI, prefix, name, "CDATA", uri);
}
}
}
return pushed;
| public void | writeAttrString(java.io.Writer writer, java.lang.String string, java.lang.String encoding)Returns the specified string after substituting specials,
and UTF-16 surrogates for chracter references &#xnn .
final int len = string.length();
if (len > m_attrBuff.length)
{
m_attrBuff = new char[len*2 + 1];
}
string.getChars(0,len, m_attrBuff, 0);
final char[] stringChars = m_attrBuff;
for (int i = 0; i < len; i++)
{
char ch = stringChars[i];
if (escapingNotNeeded(ch) && (!m_charInfo.isSpecialAttrChar(ch)))
{
writer.write(ch);
}
else
{ // I guess the parser doesn't normalize cr/lf in attributes. -sb
// if ((CharInfo.S_CARRIAGERETURN == ch)
// && ((i + 1) < len)
// && (CharInfo.S_LINEFEED == stringChars[i + 1]))
// {
// i++;
// ch = CharInfo.S_LINEFEED;
// }
accumDefaultEscape(writer, ch, i, stringChars, len, false, true);
}
}
| void | writeNormalizedChars(char[] ch, int start, int length, boolean isCData, boolean useSystemLineSeparator)Normalize the characters, but don't escape.
final java.io.Writer writer = m_writer;
int end = start + length;
for (int i = start; i < end; i++)
{
char c = ch[i];
if (CharInfo.S_LINEFEED == c && useSystemLineSeparator)
{
writer.write(m_lineSep, 0, m_lineSepLen);
}
else if (isCData && (!escapingNotNeeded(c)))
{
// if (i != 0)
if (m_cdataTagOpen)
closeCDATA();
// This needs to go into a function...
if (isUTF16Surrogate(c))
{
writeUTF16Surrogate(c, ch, i, end);
i++ ; // process two input characters
}
else
{
writer.write("");
String intStr = Integer.toString((int) c);
writer.write(intStr);
writer.write(';");
}
// if ((i != 0) && (i < (end - 1)))
// if (!m_cdataTagOpen && (i < (end - 1)))
// {
// writer.write(CDATA_DELIMITER_OPEN);
// m_cdataTagOpen = true;
// }
}
else if (
isCData
&& ((i < (end - 2))
&& (']" == c)
&& (']" == ch[i + 1])
&& ('>" == ch[i + 2])))
{
writer.write(CDATA_CONTINUE);
i += 2;
}
else
{
if (escapingNotNeeded(c))
{
if (isCData && !m_cdataTagOpen)
{
writer.write(CDATA_DELIMITER_OPEN);
m_cdataTagOpen = true;
}
writer.write(c);
}
// This needs to go into a function...
else if (isUTF16Surrogate(c))
{
if (m_cdataTagOpen)
closeCDATA();
writeUTF16Surrogate(c, ch, i, end);
i++; // process two input characters
}
else
{
if (m_cdataTagOpen)
closeCDATA();
writer.write("");
String intStr = Integer.toString((int) c);
writer.write(intStr);
writer.write(';");
}
}
}
| protected void | writeUTF16Surrogate(char c, char[] ch, int i, int end)Once a surrogate has been detected, write out the pair of
characters as a single character reference.
// UTF-16 surrogate
int surrogateValue = getURF16SurrogateValue(c, ch, i, end);
final java.io.Writer writer = m_writer;
writer.write('&");
writer.write('#");
// writer.write('x');
writer.write(Integer.toString(surrogateValue));
writer.write(';");
|
|