src/share/classes/com/sun/xml/internal/bind/v2/runtime/output/UTF8XmlOutput.java

changeset 42
99fc62f032a7
parent 1
0961a4a21176
child 46
a88ad84027a0
equal deleted inserted replaced
30:5be52db581f1 42:99fc62f032a7
20 * 20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or 22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions. 23 * have any questions.
24 */ 24 */
25
26 package com.sun.xml.internal.bind.v2.runtime.output; 25 package com.sun.xml.internal.bind.v2.runtime.output;
27 26
28 import java.io.IOException; 27 import java.io.IOException;
29 import java.io.OutputStream; 28 import java.io.OutputStream;
30 29
31 import javax.xml.stream.XMLStreamException; 30 import javax.xml.stream.XMLStreamException;
32 31
33 import com.sun.xml.internal.bind.DatatypeConverterImpl; 32 import com.sun.xml.internal.bind.DatatypeConverterImpl;
34 import com.sun.xml.internal.bind.v2.runtime.Name; 33 import com.sun.xml.internal.bind.v2.runtime.Name;
35 import com.sun.xml.internal.bind.v2.runtime.XMLSerializer; 34 import com.sun.xml.internal.bind.v2.runtime.XMLSerializer;
35 import com.sun.xml.internal.bind.v2.runtime.MarshallerImpl;
36 36
37 import org.xml.sax.SAXException; 37 import org.xml.sax.SAXException;
38 38
39 /** 39 /**
40 * {@link XmlOutput} implementation specialized for UTF-8. 40 * {@link XmlOutput} implementation specialized for UTF-8.
80 * allows us to write "/>" for empty elements. 80 * allows us to write "/>" for empty elements.
81 */ 81 */
82 protected boolean closeStartTagPending = false; 82 protected boolean closeStartTagPending = false;
83 83
84 /** 84 /**
85 * @see MarshallerImpl#header
86 */
87 private String header;
88
89 /**
85 * 90 *
86 * @param localNames 91 * @param localNames
87 * local names encoded in UTF-8. 92 * local names encoded in UTF-8.
88 */ 93 */
89 public UTF8XmlOutput(OutputStream out, Encoded[] localNames) { 94 public UTF8XmlOutput(OutputStream out, Encoded[] localNames) {
91 this.localNames = localNames; 96 this.localNames = localNames;
92 for( int i=0; i<prefixes.length; i++ ) 97 for( int i=0; i<prefixes.length; i++ )
93 prefixes[i] = new Encoded(); 98 prefixes[i] = new Encoded();
94 } 99 }
95 100
101 public void setHeader(String header) {
102 this.header = header;
103 }
104
96 @Override 105 @Override
97 public void startDocument(XMLSerializer serializer, boolean fragment, int[] nsUriIndex2prefixIndex, NamespaceContextImpl nsContext) throws IOException, SAXException, XMLStreamException { 106 public void startDocument(XMLSerializer serializer, boolean fragment, int[] nsUriIndex2prefixIndex, NamespaceContextImpl nsContext) throws IOException, SAXException, XMLStreamException {
98 super.startDocument(serializer, fragment,nsUriIndex2prefixIndex,nsContext); 107 super.startDocument(serializer, fragment,nsUriIndex2prefixIndex,nsContext);
99 108
100 octetBufferIndex = 0; 109 octetBufferIndex = 0;
101 if(!fragment) { 110 if(!fragment) {
102 write(XML_DECL); 111 write(XML_DECL);
112 }
113 if(header!=null) {
114 textBuffer.set(header);
115 textBuffer.write(this);
103 } 116 }
104 } 117 }
105 118
106 public void endDocument(boolean fragment) throws IOException, SAXException, XMLStreamException { 119 public void endDocument(boolean fragment) throws IOException, SAXException, XMLStreamException {
107 flushBuffer(); 120 flushBuffer();
375 protected final void flushBuffer() throws IOException { 388 protected final void flushBuffer() throws IOException {
376 out.write(octetBuffer, 0, octetBufferIndex); 389 out.write(octetBuffer, 0, octetBufferIndex);
377 octetBufferIndex = 0; 390 octetBufferIndex = 0;
378 } 391 }
379 392
380 public void flush() throws IOException {
381 flushBuffer();
382 out.flush();
383 }
384
385
386
387 static byte[] toBytes(String s) { 393 static byte[] toBytes(String s) {
388 byte[] buf = new byte[s.length()]; 394 byte[] buf = new byte[s.length()];
389 for( int i=s.length()-1; i>=0; i-- ) 395 for( int i=s.length()-1; i>=0; i-- )
390 buf[i] = (byte)s.charAt(i); 396 buf[i] = (byte)s.charAt(i);
391 return buf; 397 return buf;
392 } 398 }
393 399
394 private static final byte[] XMLNS_EQUALS = toBytes(" xmlns=\""); 400 // per instance copy to prevent an attack where malicious OutputStream
395 private static final byte[] XMLNS_COLON = toBytes(" xmlns:"); 401 // rewrites the byte array.
396 private static final byte[] EQUALS = toBytes("=\""); 402 private final byte[] XMLNS_EQUALS = _XMLNS_EQUALS.clone();
397 private static final byte[] CLOSE_TAG = toBytes("</"); 403 private final byte[] XMLNS_COLON = _XMLNS_COLON.clone();
398 private static final byte[] EMPTY_TAG = toBytes("/>"); 404 private final byte[] EQUALS = _EQUALS.clone();
405 private final byte[] CLOSE_TAG = _CLOSE_TAG.clone();
406 private final byte[] EMPTY_TAG = _EMPTY_TAG.clone();
407 private final byte[] XML_DECL = _XML_DECL.clone();
408
409 // masters
410 private static final byte[] _XMLNS_EQUALS = toBytes(" xmlns=\"");
411 private static final byte[] _XMLNS_COLON = toBytes(" xmlns:");
412 private static final byte[] _EQUALS = toBytes("=\"");
413 private static final byte[] _CLOSE_TAG = toBytes("</");
414 private static final byte[] _EMPTY_TAG = toBytes("/>");
415 private static final byte[] _XML_DECL = toBytes("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
416
417 // no need to copy
399 private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; 418 private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
400 private static final byte[] XML_DECL = toBytes("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
401 } 419 }

mercurial