src/share/jaxws_classes/com/sun/xml/internal/fastinfoset/stax/StAXDocumentSerializer.java

changeset 0
373ffda63c9a
equal deleted inserted replaced
-1:000000000000 0:373ffda63c9a
1 /*
2 * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 *
25 * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
26 */
27
28 package com.sun.xml.internal.fastinfoset.stax;
29
30 import com.sun.xml.internal.fastinfoset.Encoder;
31 import com.sun.xml.internal.fastinfoset.EncodingConstants;
32 import com.sun.xml.internal.fastinfoset.util.NamespaceContextImplementation;
33 import java.io.IOException;
34 import java.io.OutputStream;
35 import java.util.EmptyStackException;
36 import javax.xml.namespace.NamespaceContext;
37 import javax.xml.stream.XMLStreamException;
38 import javax.xml.stream.XMLStreamWriter;
39 import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
40 import com.sun.xml.internal.fastinfoset.CommonResourceBundle;
41 import com.sun.xml.internal.fastinfoset.QualifiedName;
42 import com.sun.xml.internal.fastinfoset.util.LocalNameQualifiedNamesMap;
43 import com.sun.xml.internal.org.jvnet.fastinfoset.stax.LowLevelFastInfosetStreamWriter;
44
45 /**
46 * The Fast Infoset StAX serializer.
47 * <p>
48 * Instantiate this serializer to serialize a fast infoset document in accordance
49 * with the StAX API.
50 *
51 * <p>
52 * More than one fast infoset document may be encoded to the
53 * {@link java.io.OutputStream}.
54 */
55 public class StAXDocumentSerializer extends Encoder
56 implements XMLStreamWriter, LowLevelFastInfosetStreamWriter {
57 protected StAXManager _manager;
58
59 protected String _encoding;
60 /**
61 * Local name of current element.
62 */
63 protected String _currentLocalName;
64
65 /**
66 * Namespace of current element.
67 */
68 protected String _currentUri;
69
70 /**
71 * Prefix of current element.
72 */
73 protected String _currentPrefix;
74
75 /**
76 * This flag indicates when there is a pending start element event.
77 */
78 protected boolean _inStartElement = false;
79
80 /**
81 * This flag indicates if the current element is empty.
82 */
83 protected boolean _isEmptyElement = false;
84
85 /**
86 * List of attributes qnames and values defined in the current element.
87 */
88 protected String[] _attributesArray = new String[4 * 16];
89 protected int _attributesArrayIndex = 0;
90
91 protected boolean[] _nsSupportContextStack = new boolean[32];
92 protected int _stackCount = -1;
93
94 /**
95 * Mapping between uris and prefixes.
96 */
97 protected NamespaceContextImplementation _nsContext =
98 new NamespaceContextImplementation();
99
100 /**
101 * List of namespaces defined in the current element.
102 */
103 protected String[] _namespacesArray = new String[2 * 8];
104 protected int _namespacesArrayIndex = 0;
105
106 public StAXDocumentSerializer() {
107 super(true);
108 _manager = new StAXManager(StAXManager.CONTEXT_WRITER);
109 }
110
111 public StAXDocumentSerializer(OutputStream outputStream) {
112 super(true);
113 setOutputStream(outputStream);
114 _manager = new StAXManager(StAXManager.CONTEXT_WRITER);
115 }
116
117 public StAXDocumentSerializer(OutputStream outputStream, StAXManager manager) {
118 super(true);
119 setOutputStream(outputStream);
120 _manager = manager;
121 }
122
123 public void reset() {
124 super.reset();
125
126 _attributesArrayIndex = 0;
127 _namespacesArrayIndex = 0;
128
129 _nsContext.reset();
130 _stackCount = -1;
131
132 _currentUri = _currentPrefix = null;
133 _currentLocalName = null;
134
135 _inStartElement = _isEmptyElement = false;
136 }
137
138 // -- XMLStreamWriter Interface -------------------------------------------
139
140 public void writeStartDocument() throws XMLStreamException {
141 writeStartDocument("finf", "1.0");
142 }
143
144 public void writeStartDocument(String version) throws XMLStreamException {
145 writeStartDocument("finf", version);
146 }
147
148 public void writeStartDocument(String encoding, String version)
149 throws XMLStreamException
150 {
151 reset();
152
153 try {
154 encodeHeader(false);
155 encodeInitialVocabulary();
156 } catch (IOException e) {
157 throw new XMLStreamException(e);
158 }
159 }
160
161 public void writeEndDocument() throws XMLStreamException {
162 try {
163
164 // terminate all elements not terminated
165 // by writeEndElement
166 for(;_stackCount >= 0; _stackCount--) {
167 writeEndElement();
168 }
169
170 encodeDocumentTermination();
171 }
172 catch (IOException e) {
173 throw new XMLStreamException(e);
174 }
175 }
176
177 public void close() throws XMLStreamException {
178 reset();
179 }
180
181 public void flush() throws XMLStreamException {
182 try {
183 _s.flush();
184 }
185 catch (IOException e) {
186 throw new XMLStreamException(e);
187 }
188 }
189
190 public void writeStartElement(String localName)
191 throws XMLStreamException
192 {
193 // TODO is it necessary for FI to obtain the default namespace in scope?
194 writeStartElement("", localName, "");
195 }
196
197 public void writeStartElement(String namespaceURI, String localName)
198 throws XMLStreamException
199 {
200 writeStartElement("", localName, namespaceURI);
201 }
202
203 public void writeStartElement(String prefix, String localName,
204 String namespaceURI) throws XMLStreamException
205 {
206 encodeTerminationAndCurrentElement(false);
207
208 _inStartElement = true;
209 _isEmptyElement = false;
210
211 _currentLocalName = localName;
212 _currentPrefix = prefix;
213 _currentUri = namespaceURI;
214
215 _stackCount++;
216 if (_stackCount == _nsSupportContextStack.length) {
217 boolean[] nsSupportContextStack = new boolean[_stackCount * 2];
218 System.arraycopy(_nsSupportContextStack, 0, nsSupportContextStack, 0, _nsSupportContextStack.length);
219 _nsSupportContextStack = nsSupportContextStack;
220 }
221
222 _nsSupportContextStack[_stackCount] = false;
223 }
224
225 public void writeEmptyElement(String localName)
226 throws XMLStreamException
227 {
228 writeEmptyElement("", localName, "");
229 }
230
231 public void writeEmptyElement(String namespaceURI, String localName)
232 throws XMLStreamException
233 {
234 writeEmptyElement("", localName, namespaceURI);
235 }
236
237 public void writeEmptyElement(String prefix, String localName,
238 String namespaceURI) throws XMLStreamException
239 {
240 encodeTerminationAndCurrentElement(false);
241
242 _isEmptyElement = _inStartElement = true;
243
244 _currentLocalName = localName;
245 _currentPrefix = prefix;
246 _currentUri = namespaceURI;
247
248 _stackCount++;
249 if (_stackCount == _nsSupportContextStack.length) {
250 boolean[] nsSupportContextStack = new boolean[_stackCount * 2];
251 System.arraycopy(_nsSupportContextStack, 0, nsSupportContextStack, 0, _nsSupportContextStack.length);
252 _nsSupportContextStack = nsSupportContextStack;
253 }
254
255 _nsSupportContextStack[_stackCount] = false;
256 }
257
258 public void writeEndElement() throws XMLStreamException {
259 if (_inStartElement) {
260 encodeTerminationAndCurrentElement(false);
261 }
262
263 try {
264 encodeElementTermination();
265 if (_nsSupportContextStack[_stackCount--] == true) {
266 _nsContext.popContext();
267 }
268 }
269 catch (IOException e) {
270 throw new XMLStreamException(e);
271 }
272 catch (EmptyStackException e) {
273 throw new XMLStreamException(e);
274 }
275 }
276
277
278 public void writeAttribute(String localName, String value)
279 throws XMLStreamException
280 {
281 writeAttribute("", "", localName, value);
282 }
283
284 public void writeAttribute(String namespaceURI, String localName,
285 String value) throws XMLStreamException
286 {
287 String prefix = "";
288
289 // Find prefix for attribute, ignoring default namespace
290 if (namespaceURI.length() > 0) {
291 prefix = _nsContext.getNonDefaultPrefix(namespaceURI);
292
293 // Undeclared prefix or ignorable default ns?
294 if (prefix == null || prefix.length() == 0) {
295 // Workaround for BUG in SAX NamespaceSupport helper
296 // which incorrectly defines namespace declaration URI
297 if (namespaceURI == EncodingConstants.XMLNS_NAMESPACE_NAME ||
298 namespaceURI.equals(EncodingConstants.XMLNS_NAMESPACE_NAME)) {
299 // TODO
300 // Need to check carefully the rule for the writing of
301 // namespaces in StAX. Is it safe to ignore such
302 // attributes, as declarations will be made using the
303 // writeNamespace method
304 return;
305 }
306 throw new XMLStreamException(CommonResourceBundle.getInstance().getString("message.URIUnbound", new Object[]{namespaceURI}));
307 }
308 }
309 writeAttribute(prefix, namespaceURI, localName, value);
310 }
311
312 public void writeAttribute(String prefix, String namespaceURI,
313 String localName, String value) throws XMLStreamException
314 {
315 if (!_inStartElement) {
316 throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.attributeWritingNotAllowed"));
317 }
318
319 // TODO
320 // Need to check carefully the rule for the writing of
321 // namespaces in StAX. Is it safe to ignore such
322 // attributes, as declarations will be made using the
323 // writeNamespace method
324 if (namespaceURI == EncodingConstants.XMLNS_NAMESPACE_NAME ||
325 namespaceURI.equals(EncodingConstants.XMLNS_NAMESPACE_NAME)) {
326 return;
327 }
328
329 if (_attributesArrayIndex == _attributesArray.length) {
330 final String[] attributesArray = new String[_attributesArrayIndex * 2];
331 System.arraycopy(_attributesArray, 0, attributesArray, 0, _attributesArrayIndex);
332 _attributesArray = attributesArray;
333 }
334
335 _attributesArray[_attributesArrayIndex++] = namespaceURI;
336 _attributesArray[_attributesArrayIndex++] = prefix;
337 _attributesArray[_attributesArrayIndex++] = localName;
338 _attributesArray[_attributesArrayIndex++] = value;
339 }
340
341 public void writeNamespace(String prefix, String namespaceURI)
342 throws XMLStreamException
343 {
344 if (prefix == null || prefix.length() == 0 || prefix.equals(EncodingConstants.XMLNS_NAMESPACE_PREFIX)) {
345 writeDefaultNamespace(namespaceURI);
346 }
347 else {
348 if (!_inStartElement) {
349 throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.attributeWritingNotAllowed"));
350 }
351
352 if (_namespacesArrayIndex == _namespacesArray.length) {
353 final String[] namespacesArray = new String[_namespacesArrayIndex * 2];
354 System.arraycopy(_namespacesArray, 0, namespacesArray, 0, _namespacesArrayIndex);
355 _namespacesArray = namespacesArray;
356 }
357
358 _namespacesArray[_namespacesArrayIndex++] = prefix;
359 _namespacesArray[_namespacesArrayIndex++] = namespaceURI;
360 setPrefix(prefix, namespaceURI);
361 }
362 }
363
364 public void writeDefaultNamespace(String namespaceURI)
365 throws XMLStreamException
366 {
367 if (!_inStartElement) {
368 throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.attributeWritingNotAllowed"));
369 }
370
371 if (_namespacesArrayIndex == _namespacesArray.length) {
372 final String[] namespacesArray = new String[_namespacesArrayIndex * 2];
373 System.arraycopy(_namespacesArray, 0, namespacesArray, 0, _namespacesArrayIndex);
374 _namespacesArray = namespacesArray;
375 }
376
377 _namespacesArray[_namespacesArrayIndex++] = "";
378 _namespacesArray[_namespacesArrayIndex++] = namespaceURI;
379 setPrefix("", namespaceURI);
380 }
381
382 public void writeComment(String data) throws XMLStreamException {
383 try {
384 if (getIgnoreComments()) return;
385
386 encodeTerminationAndCurrentElement(true);
387
388 // TODO: avoid array copy here
389 encodeComment(data.toCharArray(), 0, data.length());
390 }
391 catch (IOException e) {
392 throw new XMLStreamException(e);
393 }
394 }
395
396 public void writeProcessingInstruction(String target)
397 throws XMLStreamException
398 {
399 writeProcessingInstruction(target, "");
400 }
401
402 public void writeProcessingInstruction(String target, String data)
403 throws XMLStreamException
404 {
405 try {
406 if (getIgnoreProcesingInstructions()) return;
407
408 encodeTerminationAndCurrentElement(true);
409
410 encodeProcessingInstruction(target, data);
411 }
412 catch (IOException e) {
413 throw new XMLStreamException(e);
414 }
415 }
416
417 public void writeCData(String text) throws XMLStreamException {
418 try {
419 final int length = text.length();
420 if (length == 0) {
421 return;
422 } else if (length < _charBuffer.length) {
423 if (getIgnoreWhiteSpaceTextContent() &&
424 isWhiteSpace(text)) return;
425
426 // Warning: this method must be called before any state
427 // is modified, such as the _charBuffer contents,
428 // so the characters of text cannot be copied to _charBuffer
429 // before this call
430 encodeTerminationAndCurrentElement(true);
431
432 text.getChars(0, length, _charBuffer, 0);
433 encodeCIIBuiltInAlgorithmDataAsCDATA(_charBuffer, 0, length);
434 } else {
435 final char ch[] = text.toCharArray();
436 if (getIgnoreWhiteSpaceTextContent() &&
437 isWhiteSpace(ch, 0, length)) return;
438
439 encodeTerminationAndCurrentElement(true);
440
441 encodeCIIBuiltInAlgorithmDataAsCDATA(ch, 0, length);
442 }
443 } catch (Exception e) {
444 throw new XMLStreamException(e);
445 }
446 }
447
448 public void writeDTD(String dtd) throws XMLStreamException {
449 throw new UnsupportedOperationException(CommonResourceBundle.getInstance().getString("message.notImplemented"));
450 }
451
452 public void writeEntityRef(String name) throws XMLStreamException {
453 throw new UnsupportedOperationException(CommonResourceBundle.getInstance().getString("message.notImplemented"));
454 }
455
456 public void writeCharacters(String text) throws XMLStreamException {
457 try {
458 final int length = text.length();
459 if (length == 0) {
460 return;
461 } else if (length < _charBuffer.length) {
462 if (getIgnoreWhiteSpaceTextContent() &&
463 isWhiteSpace(text)) return;
464
465 // Warning: this method must be called before any state
466 // is modified, such as the _charBuffer contents,
467 // so the characters of text cannot be copied to _charBuffer
468 // before this call
469 encodeTerminationAndCurrentElement(true);
470
471 text.getChars(0, length, _charBuffer, 0);
472 encodeCharacters(_charBuffer, 0, length);
473 } else {
474 final char ch[] = text.toCharArray();
475 if (getIgnoreWhiteSpaceTextContent() &&
476 isWhiteSpace(ch, 0, length)) return;
477
478 encodeTerminationAndCurrentElement(true);
479
480 encodeCharactersNoClone(ch, 0, length);
481 }
482 }
483 catch (IOException e) {
484 throw new XMLStreamException(e);
485 }
486 }
487
488 public void writeCharacters(char[] text, int start, int len)
489 throws XMLStreamException
490 {
491 try {
492 if (len <= 0) {
493 return;
494 }
495
496 if (getIgnoreWhiteSpaceTextContent() &&
497 isWhiteSpace(text, start, len)) return;
498
499 encodeTerminationAndCurrentElement(true);
500
501 encodeCharacters(text, start, len);
502 }
503 catch (IOException e) {
504 throw new XMLStreamException(e);
505 }
506 }
507
508 public String getPrefix(String uri) throws XMLStreamException {
509 return _nsContext.getPrefix(uri);
510 }
511
512 public void setPrefix(String prefix, String uri)
513 throws XMLStreamException
514 {
515 if (_stackCount > -1 && _nsSupportContextStack[_stackCount] == false) {
516 _nsSupportContextStack[_stackCount] = true;
517 _nsContext.pushContext();
518 }
519
520 _nsContext.declarePrefix(prefix, uri);
521 }
522
523 public void setDefaultNamespace(String uri) throws XMLStreamException {
524 setPrefix("", uri);
525 }
526
527 /**
528 * Sets the current namespace context for prefix and uri bindings.
529 * This context becomes the root namespace context for writing and
530 * will replace the current root namespace context. Subsequent calls
531 * to setPrefix and setDefaultNamespace will bind namespaces using
532 * the context passed to the method as the root context for resolving
533 * namespaces. This method may only be called once at the start of
534 * the document. It does not cause the namespaces to be declared.
535 * If a namespace URI to prefix mapping is found in the namespace
536 * context it is treated as declared and the prefix may be used
537 * by the StreamWriter.
538 * @param context the namespace context to use for this writer, may not be null
539 * @throws XMLStreamException
540 */
541 public void setNamespaceContext(NamespaceContext context)
542 throws XMLStreamException
543 {
544 throw new UnsupportedOperationException("setNamespaceContext");
545 }
546
547 public NamespaceContext getNamespaceContext() {
548 return _nsContext;
549 }
550
551 public Object getProperty(java.lang.String name)
552 throws IllegalArgumentException
553 {
554 if (_manager != null) {
555 return _manager.getProperty(name);
556 }
557 return null;
558 }
559
560 public void setManager(StAXManager manager) {
561 _manager = manager;
562 }
563
564 public void setEncoding(String encoding) {
565 _encoding = encoding;
566 }
567
568
569 public void writeOctets(byte[] b, int start, int len)
570 throws XMLStreamException
571 {
572 try {
573 if (len == 0) {
574 return;
575 }
576
577 encodeTerminationAndCurrentElement(true);
578
579 encodeCIIOctetAlgorithmData(EncodingAlgorithmIndexes.BASE64, b, start, len);
580 }
581 catch (IOException e) {
582 throw new XMLStreamException(e);
583 }
584 }
585
586 protected void encodeTerminationAndCurrentElement(boolean terminateAfter) throws XMLStreamException {
587 try {
588 encodeTermination();
589
590 if (_inStartElement) {
591
592 _b = EncodingConstants.ELEMENT;
593 if (_attributesArrayIndex > 0) {
594 _b |= EncodingConstants.ELEMENT_ATTRIBUTE_FLAG;
595 }
596
597 // Encode namespace decls associated with this element
598 if (_namespacesArrayIndex > 0) {
599 write(_b | EncodingConstants.ELEMENT_NAMESPACES_FLAG);
600 for (int i = 0; i < _namespacesArrayIndex;) {
601 encodeNamespaceAttribute(_namespacesArray[i++], _namespacesArray[i++]);
602 }
603 _namespacesArrayIndex = 0;
604
605 write(EncodingConstants.TERMINATOR);
606
607 _b = 0;
608 }
609
610 // If element's prefix is empty - apply default scope namespace
611 if (_currentPrefix.length() == 0) {
612 if (_currentUri.length() == 0) {
613 _currentUri = _nsContext.getNamespaceURI("");
614 } else {
615 String tmpPrefix = getPrefix(_currentUri);
616 if (tmpPrefix != null) {
617 _currentPrefix = tmpPrefix;
618 }
619 }
620 }
621
622 encodeElementQualifiedNameOnThirdBit(_currentUri, _currentPrefix, _currentLocalName);
623
624 for (int i = 0; i < _attributesArrayIndex;) {
625 encodeAttributeQualifiedNameOnSecondBit(
626 _attributesArray[i++], _attributesArray[i++], _attributesArray[i++]);
627
628 final String value = _attributesArray[i];
629 _attributesArray[i++] = null;
630 final boolean addToTable = isAttributeValueLengthMatchesLimit(value.length());
631 encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable, false);
632
633 _b = EncodingConstants.TERMINATOR;
634 _terminate = true;
635 }
636 _attributesArrayIndex = 0;
637 _inStartElement = false;
638
639 if (_isEmptyElement) {
640 encodeElementTermination();
641 if (_nsSupportContextStack[_stackCount--] == true) {
642 _nsContext.popContext();
643 }
644
645 _isEmptyElement = false;
646 }
647
648 if (terminateAfter) {
649 encodeTermination();
650 }
651 }
652 } catch (IOException e) {
653 throw new XMLStreamException(e);
654 }
655 }
656
657
658 // LowLevelFastInfosetSerializer
659
660 public final void initiateLowLevelWriting() throws XMLStreamException {
661 encodeTerminationAndCurrentElement(false);
662 }
663
664 public final int getNextElementIndex() {
665 return _v.elementName.getNextIndex();
666 }
667
668 public final int getNextAttributeIndex() {
669 return _v.attributeName.getNextIndex();
670 }
671
672 public final int getLocalNameIndex() {
673 return _v.localName.getIndex();
674 }
675
676 public final int getNextLocalNameIndex() {
677 return _v.localName.getNextIndex();
678 }
679
680 public final void writeLowLevelTerminationAndMark() throws IOException {
681 encodeTermination();
682 mark();
683 }
684
685 public final void writeLowLevelStartElementIndexed(int type, int index) throws IOException {
686 _b = type;
687 encodeNonZeroIntegerOnThirdBit(index);
688 }
689
690 public final boolean writeLowLevelStartElement(int type, String prefix, String localName,
691 String namespaceURI) throws IOException {
692 final boolean isIndexed = encodeElement(type, namespaceURI, prefix, localName);
693
694 if (!isIndexed)
695 encodeLiteral(type | EncodingConstants.ELEMENT_LITERAL_QNAME_FLAG,
696 namespaceURI, prefix, localName);
697
698 return isIndexed;
699 }
700
701 public final void writeLowLevelStartNamespaces() throws IOException {
702 write(EncodingConstants.ELEMENT | EncodingConstants.ELEMENT_NAMESPACES_FLAG);
703 }
704
705 public final void writeLowLevelNamespace(String prefix, String namespaceName)
706 throws IOException {
707 encodeNamespaceAttribute(prefix, namespaceName);
708 }
709
710 public final void writeLowLevelEndNamespaces() throws IOException {
711 write(EncodingConstants.TERMINATOR);
712 }
713
714 public final void writeLowLevelStartAttributes() throws IOException {
715 if (hasMark()) {
716 _octetBuffer[_markIndex] |= EncodingConstants.ELEMENT_ATTRIBUTE_FLAG;
717 resetMark();
718 }
719 }
720
721 public final void writeLowLevelAttributeIndexed(int index) throws IOException {
722 encodeNonZeroIntegerOnSecondBitFirstBitZero(index);
723 }
724
725 public final boolean writeLowLevelAttribute(String prefix, String namespaceURI, String localName) throws IOException {
726 final boolean isIndexed = encodeAttribute(namespaceURI, prefix, localName);
727
728 if (!isIndexed)
729 encodeLiteral(EncodingConstants.ATTRIBUTE_LITERAL_QNAME_FLAG,
730 namespaceURI, prefix, localName);
731
732 return isIndexed;
733 }
734
735 public final void writeLowLevelAttributeValue(String value) throws IOException
736 {
737 final boolean addToTable = isAttributeValueLengthMatchesLimit(value.length());
738 encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable, false);
739 }
740
741 public final void writeLowLevelStartNameLiteral(int type, String prefix, byte[] utf8LocalName,
742 String namespaceURI) throws IOException {
743 encodeLiteralHeader(type, namespaceURI, prefix);
744 encodeNonZeroOctetStringLengthOnSecondBit(utf8LocalName.length);
745 write(utf8LocalName, 0, utf8LocalName.length);
746 }
747
748 public final void writeLowLevelStartNameLiteral(int type, String prefix, int localNameIndex,
749 String namespaceURI) throws IOException {
750 encodeLiteralHeader(type, namespaceURI, prefix);
751 encodeNonZeroIntegerOnSecondBitFirstBitOne(localNameIndex);
752 }
753
754 public final void writeLowLevelEndStartElement() throws IOException {
755 if (hasMark()) {
756 resetMark();
757 } else {
758 // Terminate the attributes
759 _b = EncodingConstants.TERMINATOR;
760 _terminate = true;
761 }
762 }
763
764 public final void writeLowLevelEndElement() throws IOException {
765 encodeElementTermination();
766 }
767
768 public final void writeLowLevelText(char[] text, int length) throws IOException {
769 if (length == 0)
770 return;
771
772 encodeTermination();
773
774 encodeCharacters(text, 0, length);
775 }
776
777 public final void writeLowLevelText(String text) throws IOException {
778 final int length = text.length();
779 if (length == 0)
780 return;
781
782 encodeTermination();
783
784 if (length < _charBuffer.length) {
785 text.getChars(0, length, _charBuffer, 0);
786 encodeCharacters(_charBuffer, 0, length);
787 } else {
788 final char ch[] = text.toCharArray();
789 encodeCharactersNoClone(ch, 0, length);
790 }
791 }
792
793 public final void writeLowLevelOctets(byte[] octets, int length) throws IOException {
794 if (length == 0)
795 return;
796
797 encodeTermination();
798
799 encodeCIIOctetAlgorithmData(EncodingAlgorithmIndexes.BASE64, octets, 0, length);
800 }
801
802 private boolean encodeElement(int type, String namespaceURI, String prefix, String localName) throws IOException {
803 final LocalNameQualifiedNamesMap.Entry entry = _v.elementName.obtainEntry(localName);
804 for (int i = 0; i < entry._valueIndex; i++) {
805 final QualifiedName name = entry._value[i];
806 if ((prefix == name.prefix || prefix.equals(name.prefix))
807 && (namespaceURI == name.namespaceName || namespaceURI.equals(name.namespaceName))) {
808 _b = type;
809 encodeNonZeroIntegerOnThirdBit(name.index);
810 return true;
811 }
812 }
813
814 entry.addQualifiedName(new QualifiedName(prefix, namespaceURI, localName, "", _v.elementName.getNextIndex()));
815 return false;
816 }
817
818 private boolean encodeAttribute(String namespaceURI, String prefix, String localName) throws IOException {
819 final LocalNameQualifiedNamesMap.Entry entry = _v.attributeName.obtainEntry(localName);
820 for (int i = 0; i < entry._valueIndex; i++) {
821 final QualifiedName name = entry._value[i];
822 if ((prefix == name.prefix || prefix.equals(name.prefix))
823 && (namespaceURI == name.namespaceName || namespaceURI.equals(name.namespaceName))) {
824 encodeNonZeroIntegerOnSecondBitFirstBitZero(name.index);
825 return true;
826 }
827 }
828
829 entry.addQualifiedName(new QualifiedName(prefix, namespaceURI, localName, "", _v.attributeName.getNextIndex()));
830 return false;
831 }
832
833 private void encodeLiteralHeader(int type, String namespaceURI, String prefix) throws IOException {
834 if (namespaceURI != "") {
835 type |= EncodingConstants.LITERAL_QNAME_NAMESPACE_NAME_FLAG;
836 if (prefix != "")
837 type |= EncodingConstants.LITERAL_QNAME_PREFIX_FLAG;
838
839 write(type);
840 if (prefix != "")
841 encodeNonZeroIntegerOnSecondBitFirstBitOne(_v.prefix.get(prefix));
842 encodeNonZeroIntegerOnSecondBitFirstBitOne(_v.namespaceName.get(namespaceURI));
843 } else
844 write(type);
845 }
846
847 private void encodeLiteral(int type, String namespaceURI, String prefix, String localName) throws IOException {
848 encodeLiteralHeader(type, namespaceURI, prefix);
849
850 final int localNameIndex = _v.localName.obtainIndex(localName);
851 if (localNameIndex == -1) {
852 encodeNonEmptyOctetStringOnSecondBit(localName);
853 } else
854 encodeNonZeroIntegerOnSecondBitFirstBitOne(localNameIndex);
855 }
856 }

mercurial