1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 package org.metricshub.wbem.sblim.cimclient.internal.pullparser;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 import java.io.IOException;
63 import java.io.Reader;
64 import java.util.ArrayList;
65 import java.util.logging.Level;
66 import org.metricshub.wbem.sblim.cimclient.internal.cimxml.sax.XMLDefaultHandlerImpl;
67 import org.metricshub.wbem.sblim.cimclient.internal.logging.LogAndTraceBroker;
68 import org.xml.sax.Attributes;
69
70
71
72
73
74 public class XMLPullParser {
75
76
77
78
79 class XMLAttributes implements Attributes {
80
81 public int getIndex(String qName) {
82
83
84
85
86 for (int i = 0; i < XMLPullParser.this.iAttributeNames.size(); i++) {
87 XMLAttributeValue xmlAttrValue = XMLPullParser.this.iAttributeNames.get(i);
88 if (qName.equals(xmlAttrValue.toString())) return i;
89 }
90 return -1;
91 }
92
93
94
95
96
97
98 public int getIndex(String uri, String localName) {
99 return 0;
100 }
101
102 public int getLength() {
103 return XMLPullParser.this.iTotalAttributes;
104 }
105
106
107
108
109
110 public String getLocalName(int index) {
111 return EMPTY;
112 }
113
114 public String getQName(int index) {
115 return XMLPullParser.this.iAttributeNames.get(index).getText();
116 }
117
118
119
120
121
122 public String getType(int index) {
123 return EMPTY;
124 }
125
126
127
128
129
130 public String getType(String qName) {
131 return EMPTY;
132 }
133
134
135
136
137
138
139 public String getType(String uri, String localName) {
140 return EMPTY;
141 }
142
143
144
145
146
147 public String getURI(int index) {
148 return EMPTY;
149 }
150
151 public String getValue(int index) {
152 return XMLPullParser.this.iAttributeValues.get(index).getText();
153 }
154
155 public String getValue(String qName) {
156
157
158
159
160
161 int idx = getIndex(qName);
162 if (idx < 0) return null;
163 return getValue(idx);
164 }
165
166
167
168
169
170
171 public String getValue(String uri, String localName) {
172 return EMPTY;
173 }
174 }
175
176 class XMLAttributeValue {
177 int iCurrentPos;
178
179 int iBegin, iLen;
180
181 String iText;
182
183 private boolean iTranslate;
184
185
186
187
188
189
190
191
192 public XMLAttributeValue(int begin, int len, boolean translate) {
193 this.iBegin = begin;
194 this.iLen = len;
195 this.iTranslate = translate;
196 }
197
198
199
200
201
202
203
204 public XMLAttributeValue(int begin, int len) {
205 this.iBegin = begin;
206 this.iLen = len;
207 this.iTranslate = true;
208 }
209
210
211
212
213
214
215 public String getText() {
216 if (this.iText == null) {
217 if (this.iTranslate) {
218 try {
219
220
221
222
223 this.iText = _getChars();
224
225
226
227
228
229 } catch (Exception e) {
230 LogAndTraceBroker.getBroker().trace(Level.WARNING, "exception while decoding CHARACTERS XML", e);
231 this.iText = new String(XMLPullParser.this.iBufferChar, this.iBegin, this.iLen);
232 }
233 } else {
234
235
236
237
238 this.iText = new String(XMLPullParser.this.iBufferChar, this.iBegin, this.iLen);
239
240
241
242
243
244 }
245 }
246 return this.iText;
247 }
248
249
250
251
252
253
254
255
256
257
258
259 public void init(int begin, int len) {
260 this.iBegin = begin;
261 this.iLen = len;
262 this.iText = null;
263 }
264
265
266
267
268
269
270 public void setTranslate(boolean translate) {
271 this.iTranslate = translate;
272 }
273
274 @Override
275 public String toString() {
276 return getText();
277 }
278
279 protected String _getChars() throws XMLPullParserException {
280 StringBuffer attributeValue = new StringBuffer();
281 int last = this.iBegin + this.iLen;
282 char ch;
283
284 for (this.iCurrentPos = this.iBegin; this.iCurrentPos < last; this.iCurrentPos++) {
285 ch = XMLPullParser.this.iBufferChar[this.iCurrentPos];
286 if (ch == '&') {
287
288
289 int ref = parseReference();
290
291 if (ref > -1) attributeValue.append((char) ref);
292
293
294
295
296
297
298
299
300
301
302
303 } else {
304 attributeValue.append(ch);
305 }
306
307 }
308 return attributeValue.toString();
309 }
310
311 protected int parseReference() throws XMLPullParserException {
312 this.iCurrentPos++;
313 char ch1 = XMLPullParser.this.iBufferChar[this.iCurrentPos++];
314 if (ch1 == '#') {
315 ch1 = XMLPullParser.this.iBufferChar[this.iCurrentPos++];
316 if (ch1 == 'x') {
317 int value = 0;
318 do {
319 ch1 = XMLPullParser.this.iBufferChar[this.iCurrentPos++];
320 if (ch1 >= '0' && ch1 <= '9') value = value * 16 + (ch1 - '0'); else if (
321 ch1 >= 'A' && ch1 <= 'F' || ch1 >= 'a' && ch1 <= 'f'
322 ) value = value * 16 + (Character.toUpperCase(ch1) - 'A' + 10); else if (
323 ch1 == ';'
324 ) break; else throw new XMLPullParserException(
325 "invalid character while parsing hex encoded number " + escape(ch1)
326 );
327 } while (true);
328 this.iCurrentPos--;
329 return (char) value;
330 }
331 int value = 0;
332 if (ch1 >= '0' && ch1 <= '9') {
333 do {
334 if (ch1 >= '0' && ch1 <= '9') {
335 value = value * 10 + (ch1 - '0');
336 ch1 = XMLPullParser.this.iBufferChar[this.iCurrentPos++];
337 } else if (ch1 == ';') break; else throw new XMLPullParserException(
338 "invalid character while parsing decimal encoded number: " + escape(ch1)
339 );
340 } while (true);
341 this.iCurrentPos--;
342 return (char) value;
343 }
344 throw new XMLPullParserException("invalid number format");
345 }
346 int startPos = this.iCurrentPos - 1;
347 if (isValidStartElementNameChar(ch1)) {
348 do {
349 ch1 = XMLPullParser.this.iBufferChar[this.iCurrentPos++];
350 if (ch1 == ';') break;
351 if (!isValidElementNameChar(ch1)) throw new XMLPullParserException(
352 "invalid reference character " + escape(ch1)
353 );
354 } while (true);
355 } else {
356 throw new XMLPullParserException("expected valid name start character for value reference");
357 }
358 this.iCurrentPos--;
359 ch1 = XMLPullParser.this.iBufferChar[startPos];
360 char ch2 = XMLPullParser.this.iBufferChar[startPos + 1];
361 char ch3 = XMLPullParser.this.iBufferChar[startPos + 2];
362
363 if (ch1 == 'l' && ch2 == 't' && ch3 == ';') {
364 return '<';
365 } else if (ch1 == 'g' && ch2 == 't' && ch3 == ';') {
366 return '>';
367 } else {
368 char ch4 = XMLPullParser.this.iBufferChar[startPos + 3];
369 if (ch1 == 'a' && ch2 == 'm' && ch3 == 'p' && ch4 == ';') {
370 return '&';
371 }
372 char ch5 = XMLPullParser.this.iBufferChar[startPos + 4];
373 if (ch1 == 'a' && ch2 == 'p' && ch3 == 'o' && ch4 == 's' && ch5 == ';') {
374 return '\'';
375 } else if (ch1 == 'q' && ch2 == 'u' && ch3 == 'o' && ch4 == 't' && ch5 == ';') {
376 return '\"';
377 } else {
378
379 }
380 }
381 return -1;
382 }
383 }
384
385
386
387
388 public static final int ATTRIBUTE = 10;
389
390
391
392
393 public static final int CDATA = 12;
394
395
396
397
398 public static final int CHARACTERS = 4;
399
400
401
402
403 public static final int COMMENT = 5;
404
405
406
407
408 public static final int DTD = 11;
409
410
411
412
413 public static final String EMPTY = "";
414
415
416
417
418 public static final int END_DOCUMENT = 8;
419
420
421
422
423 public static final int END_ELEMENT = 2;
424
425
426
427
428 public static final int ENTITY_DECLARATION = 15;
429
430
431
432
433 public static final int ENTITY_REFERENCE = 9;
434
435
436
437
438 public static final int NAMESPACE = 13;
439
440
441
442
443 public static final int NOTATION_DECLARATION = 14;
444
445
446
447
448 public static final int PROCESSING_INSTRUCTION = 3;
449
450
451
452
453 public static final int SPACE = 6;
454
455
456
457
458 public static final int START_DOCUMENT = 7;
459
460
461
462
463 public static final int START_ELEMENT = 1;
464
465
466
467
468
469
470 public static void main(String[] args) {
471
472 }
473
474
475
476
477
478
479
480
481
482
483
484 public static boolean next(XMLPullParser reader, XMLDefaultHandlerImpl parserHdlr) throws Exception {
485 while (reader.hasNext()) {
486 int event = reader.next();
487 switch (event) {
488 case START_ELEMENT:
489 parserHdlr.startElement(EMPTY, EMPTY, reader.getElementName(), reader.getAttributes());
490 break;
491 case END_ELEMENT:
492 parserHdlr.endElement(EMPTY, EMPTY, reader.getElementName());
493
494 String lastElementName = null;
495 if (reader.getElementNames().size() > 0) {
496 ArrayList<String> elementNames = reader.getElementNames();
497 lastElementName = elementNames.get(elementNames.size() - 1);
498 }
499
500 if (lastElementName != null && lastElementName.equalsIgnoreCase("IRETURNVALUE")) {
501 return true;
502 }
503 break;
504 case CHARACTERS:
505 char[] buf = reader.getText().toCharArray();
506 parserHdlr.characters(buf, 0, buf.length);
507 break;
508 case END_DOCUMENT:
509 return false;
510 }
511 }
512 return false;
513 }
514
515 ArrayList<XMLAttributeValue> iAttributeNames = new ArrayList<XMLAttributeValue>();
516
517 Attributes iAttributes;
518
519 ArrayList<XMLAttributeValue> iAttributeValues = new ArrayList<XMLAttributeValue>();
520
521 char[] iBufferChar = null;
522
523 XMLAttributeValue iCharacters;
524
525 boolean iClosingElementNamePending;
526
527 int iColNumber = 1;
528
529 int iCurrentPosition = 0;
530
531 int iCurrentState = 0;
532
533 String iElementName;
534
535 ArrayList<String> iElementNames = new ArrayList<String>();
536
537 int iEndCharacters;
538
539 int iFinishChar = 0;
540
541 Reader iInstream;
542
543
544
545
546 boolean iClosed;
547
548 int iLineNumber = 1;
549
550 boolean iSeenEpilog;
551
552 boolean iSeenProlog;
553
554 int iStartCharacters;
555
556 int iTotalAttributes;
557
558
559
560
561
562
563 public XMLPullParser(Reader in) {
564 this.iInstream = in;
565 reset();
566 }
567
568
569
570
571
572
573 public void close() throws IOException {
574 if (this.iClosed) return;
575 this.iClosed = true;
576 this.iInstream.close();
577 }
578
579
580
581
582
583
584 public Attributes getAttributes() {
585 if (this.iCurrentState != START_ELEMENT) return null;
586
587 if (this.iAttributes == null) {
588 this.iAttributes = new XMLAttributes();
589 }
590 return this.iAttributes;
591 }
592
593
594
595
596
597
598 public String getElementName() {
599 return this.iElementName;
600 }
601
602
603
604
605
606
607 public ArrayList<String> getElementNames() {
608 return this.iElementNames;
609 }
610
611
612
613
614
615
616 public int getLevel() {
617 return this.iElementNames.size();
618 }
619
620
621
622
623
624
625 public String getText() {
626 String result = null;
627 if (this.iCurrentState == CHARACTERS && this.iCharacters != null) {
628 return this.iCharacters.getText();
629 }
630 return result;
631 }
632
633
634
635
636
637
638 public boolean hasNext() {
639 return !this.iClosed && this.iCurrentState != END_DOCUMENT;
640 }
641
642
643
644
645
646
647
648 public int next() throws IOException {
649 char ch;
650 resetAttributes();
651 ensureCapacity();
652 if (this.iClosingElementNamePending) {
653 this.iClosingElementNamePending = false;
654 this.iElementNames.remove(this.iElementNames.size() - 1);
655 this.iCurrentState = END_ELEMENT;
656 return this.iCurrentState;
657 }
658 do {
659 ch = (char) getNextCharCheckingEOF();
660 if (ch == '<') {
661 ch = (char) getNextChar();
662 if (ch == '?') {
663 if (this.iSeenProlog) {
664 throw new XMLPullParserException(
665 "The processing instruction target matching \"[xX][mM][lL]\" is not allowed."
666 );
667 }
668 this.iSeenProlog = true;
669 parsePI();
670 ch = (char) getNextChar();
671 ch = skipOptionalSpaces(ch);
672 if (ch != '<') throw new XMLPullParserException(this, "Content is not allowed in prolog.");
673 goBack();
674
675 this.iCurrentState = START_DOCUMENT;
676 return this.iCurrentState;
677 } else if (ch == '!') {
678 ch = (char) getNextChar();
679 if (ch == '-') {
680 parseComment();
681
682 this.iCurrentState = COMMENT;
683 return this.iCurrentState;
684 } else if (ch == '[') {
685 parseCDATA();
686 this.iCurrentState = CHARACTERS;
687 return this.iCurrentState;
688 } else throw new XMLPullParserException(this, "unexpected char " + escape(ch));
689 } else if (ch == '/') {
690 parseEndElement();
691 this.iCurrentState = END_ELEMENT;
692 return this.iCurrentState;
693 } else if (ch == '&') {
694 parseUnknown();
695 } else if (isValidStartElementNameChar(ch)) {
696 if (!this.iSeenProlog) {
697 this.iSeenProlog = true;
698 this.iCurrentState = START_DOCUMENT;
699 goBack();
700 goBack();
701 return this.iCurrentState;
702 }
703 parseStartElement(ch);
704 this.iCurrentState = START_ELEMENT;
705 return this.iCurrentState;
706 } else {
707 throw new XMLPullParserException(this, "unexpected char " + escape(ch));
708 }
709 } else {
710 this.iStartCharacters = this.iCurrentPosition - 1;
711 boolean amp = false;
712
713
714 do {
715
716
717
718 ch = (char) getNextCharCheckingEOF();
719 if (ch == (char) -1) {
720 if (this.iElementNames.size() != 0) throw new XMLPullParserException(this, "unexpected EOF ");
721
722 this.iCurrentState = END_DOCUMENT;
723 return this.iCurrentState;
724 } else if (ch == '\r' || ch == '\n') {
725
726 } else {
727 if (!isSpace(ch) && ch != '<' && this.iElementNames.size() == 0) {
728 if (!this.iSeenProlog) throw new XMLPullParserException(
729 this,
730 "Content is not allowed in trailing section."
731 );
732 throw new XMLPullParserException(this, "Content is not allowed in trailing section.");
733 }
734 }
735 amp = false;
736 if (ch == '&') {
737 amp = true;
738 int i = parseReference();
739 ch = (char) (i & 0xFFFF);
740 }
741 } while (ch != '<' || amp);
742 this.iEndCharacters = this.iCurrentPosition;
743 goBack();
744 if (this.iElementNames.size() > 0) {
745 if (this.iCharacters == null) this.iCharacters =
746 new XMLAttributeValue(this.iStartCharacters, this.iEndCharacters - this.iStartCharacters - 1); else {
747 this.iCharacters.init(this.iStartCharacters, this.iEndCharacters - this.iStartCharacters - 1);
748 this.iCharacters.setTranslate(true);
749 }
750
751 this.iCurrentState = CHARACTERS;
752 return this.iCurrentState;
753 }
754 }
755 } while (true);
756 }
757
758
759
760
761 public void reset() {
762 this.iSeenProlog = true;
763 this.iCurrentState = 0;
764 this.iClosingElementNamePending = false;
765 this.iColNumber = 1;
766 this.iLineNumber = 1;
767 this.iElementName = null;
768 this.iElementNames.clear();
769 this.iAttributeNames.clear();
770 this.iAttributeValues.clear();
771 this.iAttributes = null;
772
773 this.iStartCharacters = 0;
774 this.iEndCharacters = 0;
775
776 this.iTotalAttributes = 0;
777 this.iSeenProlog = false;
778 this.iSeenEpilog = false;
779 }
780
781 @Override
782 public String toString() {
783 switch (this.iCurrentState) {
784 case START_ELEMENT: {
785 StringBuilder sb = new StringBuilder("START ELEM: <");
786 sb.append(this.iElementName);
787 if (this.iAttributeNames.size() > 0) {
788 sb.append(" ");
789 for (int i = 0; i < this.iAttributeNames.size(); i++) {
790 sb.append(this.iAttributeNames.get(i));
791 sb.append("=\"");
792 sb.append(this.iAttributeValues.get(i));
793 sb.append("\" ");
794 }
795 }
796 sb.append(">");
797 return sb.toString();
798 }
799 case END_ELEMENT: {
800 String s = "END ELEM: </" + this.iElementName + ">";
801 return s;
802 }
803 case CHARACTERS: {
804 return "CHARACTERS: \"" + getText();
805
806
807
808 }
809 }
810 return "UNKOWN";
811 }
812
813 protected char _getNextChar() {
814 return (char) -1;
815 }
816
817 protected void addAttribute(int begName, int lenName, int begValue, int lenValue) {
818 if (this.iAttributeNames.size() > this.iTotalAttributes) {
819 XMLAttributeValue attribute = this.iAttributeValues.get(this.iTotalAttributes);
820 XMLAttributeValue name = this.iAttributeNames.get(this.iTotalAttributes);
821 this.iTotalAttributes++;
822 attribute.init(begValue, lenValue);
823 attribute.setTranslate(true);
824 name.init(begName, lenName);
825 name.setTranslate(false);
826 } else {
827 XMLAttributeValue attribute = new XMLAttributeValue(begValue, lenValue);
828 XMLAttributeValue name = new XMLAttributeValue(begName, lenName, false);
829 this.iTotalAttributes++;
830 this.iAttributeNames.add(name);
831 this.iAttributeValues.add(attribute);
832 }
833 }
834
835 protected void ensureCapacity() {
836 if (this.iBufferChar == null) this.iBufferChar = new char[1024];
837
838 if (this.iCurrentPosition >= (8 * this.iBufferChar.length) / 10) {
839 System.arraycopy(
840 this.iBufferChar,
841 this.iCurrentPosition,
842 this.iBufferChar,
843 0,
844 this.iFinishChar - this.iCurrentPosition
845 );
846 this.iFinishChar -= this.iCurrentPosition;
847 this.iCurrentPosition = 0;
848 }
849 }
850
851 protected String escape(char ch) {
852 String result;
853 if (ch == '\n') result = "\'\\n\'";
854 if (ch == '\r') result = "\'\\r\'";
855 if (ch == '\t') result = "\'\\t\'";
856 if (ch == '\'') result = "\'\\'\'";
857 if (ch > '\177' || ch < ' ') result = "\'\\u" + Integer.toHexString(ch) + "\'"; else result = "\'" + ch + "\'";
858 return result;
859 }
860
861 protected int getChar() throws IOException {
862 if (this.iFinishChar <= this.iCurrentPosition) {
863 if (this.iBufferChar == null) {
864 this.iBufferChar = new char[1024];
865 } else if (this.iFinishChar >= this.iBufferChar.length) {
866 char[] tmp = this.iBufferChar;
867 this.iBufferChar = new char[this.iBufferChar.length << 1];
868 System.arraycopy(tmp, 0, this.iBufferChar, 0, tmp.length);
869 }
870
871 int total = this.iInstream.read(this.iBufferChar, this.iFinishChar, this.iBufferChar.length - this.iFinishChar);
872
873 if (total <= 0) {
874 return -1;
875 }
876 this.iFinishChar += total;
877 }
878 return this.iBufferChar[this.iCurrentPosition++];
879 }
880
881 protected int getNextChar() throws IOException {
882 int ch;
883
884 if (this.iFinishChar <= this.iCurrentPosition) {
885 ch = getChar();
886 } else ch = this.iBufferChar[this.iCurrentPosition++];
887
888 if (ch == -1) throw new XMLPullParserException(this, "unexpected end of document");
889 if (ch == '\n') {
890 this.iLineNumber++;
891 this.iColNumber = 1;
892 } else this.iColNumber++;
893
894 return (char) ch;
895 }
896
897 protected int getNextCharCheckingEOF() throws IOException {
898 int ch;
899
900 if (this.iFinishChar <= this.iCurrentPosition) {
901 ch = getChar();
902 } else ch = this.iBufferChar[this.iCurrentPosition++];
903
904 if (ch == '\n') {
905 this.iLineNumber++;
906 this.iColNumber = 1;
907 } else this.iColNumber++;
908
909 return (char) ch;
910 }
911
912 protected void goBack() {
913 this.iCurrentPosition--;
914 if (this.iColNumber > 1) {
915 this.iColNumber--;
916 }
917 }
918
919 protected boolean isSpace(char ch) {
920 return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
921 }
922
923 protected boolean isValidElementNameChar(char ch) {
924 return (
925 (
926 ch < 256 &&
927 (
928 ch >= 'A' &&
929 ch <= 'Z' ||
930 ch >= 'a' &&
931 ch <= 'z' ||
932 ch == '_' ||
933 ch == ':' ||
934 ch == '-' ||
935 ch == '.' ||
936 ch >= '0' &&
937 ch <= '9' ||
938 ch == '\267'
939 )
940 ) ||
941 ch >= '\300' &&
942 ch <= '\u02FF' ||
943 ch >= '\u0370' &&
944 ch <= '\u037D' ||
945 ch >= '\u0300' &&
946 ch <= '\u036F' ||
947 ch >= '\u037F' &&
948 ch <= '\u2027' ||
949 ch >= '\u202A' &&
950 ch <= '\u218F' ||
951 ch >= '\u2800' &&
952 ch <= '\uFFEF'
953 );
954
955
956
957
958
959
960
961
962
963 }
964
965 protected boolean isValidStartElementNameChar(char ch) {
966 return (
967 (ch < 256 && (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z' || ch == '_' || ch == ':')) ||
968 (
969 ch >= '\300' &&
970 ch <= '\u02FF' ||
971 ch >= '\u0370' &&
972 ch <= '\u037D' ||
973 ch >= '\u037F' &&
974 ch <= '\u0400' ||
975 ch >= '\u0400' &&
976 ch <= '\u2027' ||
977 ch >= '\u202A' &&
978 ch <= '\u218F' ||
979 ch >= '\u2800' &&
980 ch <= '\uFFEF'
981 )
982 );
983 }
984
985 protected void parseAttribute(char ch) throws IOException {
986 int startAttributeName = this.iCurrentPosition - 1;
987 int endAttributeName;
988
989
990 do {
991
992
993
994 ch = (char) getNextChar();
995 } while (isValidElementNameChar(ch));
996 endAttributeName = this.iCurrentPosition;
997
998
999
1000
1001 ch = skipOptionalSpaces(ch);
1002
1003 if (ch != '=') throw new XMLPullParserException(
1004 this,
1005 "missing character \'=\'instead " + escape(ch) + " was found "
1006 );
1007
1008 ch = (char) getNextChar();
1009 ch = skipOptionalSpaces(ch);
1010
1011 char delimiter;
1012 if (ch != '\"' && ch != '\'') throw new XMLPullParserException(
1013 this,
1014 "missing character \'\"\' or \'\'\' instead " + escape(ch) + " was found "
1015 );
1016 delimiter = ch;
1017
1018
1019 int startAttributeValue = this.iCurrentPosition;
1020 char prevCh = '\0';
1021
1022
1023 do {
1024
1025
1026
1027 ch = (char) getNextChar();
1028 if (ch == delimiter) break; else if (ch == '<' || ch == '>') throw new XMLPullParserException(
1029 this,
1030 "illegal character " + escape(ch)
1031 ); else if (ch == '&') {
1032 int ref = parseReference();
1033 ch = (char) (ref & 0xffff);
1034
1035 } else if (ch == '\t' || ch == '\r' || ch == '\n') {
1036 if (ch != '\n' || prevCh != '\r') {
1037
1038 }
1039 } else {
1040
1041 }
1042 prevCh = ch;
1043 } while (true);
1044 int endAttributeValue = this.iCurrentPosition;
1045
1046 addAttribute(
1047 startAttributeName,
1048 endAttributeName - startAttributeName - 1,
1049 startAttributeValue,
1050 endAttributeValue - startAttributeValue - 1
1051 );
1052
1053 return;
1054 }
1055
1056 protected int parseCDATA() throws IOException {
1057 char ch;
1058
1059 if (
1060 (char) getNextChar() != 'C' ||
1061 (char) getNextChar() != 'D' ||
1062 (char) getNextChar() != 'A' ||
1063 (char) getNextChar() != 'T' ||
1064 (char) getNextChar() != 'A' ||
1065 (char) getNextChar() != '['
1066 ) throw new XMLPullParserException("CDATA must start with \"<![CDATA[\".");
1067 boolean braketFound = false;
1068 boolean doubleBraket = false;
1069 int startCharacter = this.iCurrentPosition;
1070 do {
1071 ch = (char) getNextCharCheckingEOF();
1072 if (ch == ']') {
1073 if (braketFound) doubleBraket = true;
1074 braketFound = true;
1075 } else if (ch == '>' && doubleBraket) {
1076 break;
1077 } else {
1078 braketFound = false;
1079 doubleBraket = false;
1080 }
1081 if (ch == (char) -1) throw new XMLPullParserException(
1082 "XML document structures must start and end within the same entity."
1083 );
1084 } while (true);
1085
1086 int endCharacter = this.iCurrentPosition - 3;
1087
1088 this.iCharacters.setTranslate(false);
1089 this.iCharacters.init(startCharacter, endCharacter - startCharacter);
1090
1091 return -1;
1092 }
1093
1094 protected int parseComment() throws IOException {
1095 char ch;
1096 ch = (char) getNextChar();
1097 if (ch != '-') throw new XMLPullParserException("Comment must start with \"<!--\".");
1098 boolean dashFound = false;
1099 boolean doubleDash = false;
1100 do {
1101 ch = (char) getNextCharCheckingEOF();
1102 if (ch == '-') {
1103 if (dashFound) doubleDash = true;
1104 dashFound = true;
1105 } else if (ch == '>' && doubleDash) {
1106 break;
1107 } else {
1108 dashFound = false;
1109 doubleDash = false;
1110 }
1111 if (ch == (char) -1) throw new XMLPullParserException(
1112 "XML document structures must start and end within the same entity."
1113 );
1114 } while (true);
1115
1116
1117
1118
1119
1120
1121 return -1;
1122 }
1123
1124 protected void parseEndElement() throws IOException {
1125 int startElementName;
1126 int endElementName;
1127
1128 char ch;
1129
1130 startElementName = this.iCurrentPosition;
1131 do {
1132 ch = (char) getNextChar();
1133 } while (isValidElementNameChar(ch));
1134
1135 endElementName = this.iCurrentPosition;
1136 this.iElementName = new String(this.iBufferChar, startElementName, endElementName - startElementName - 1);
1137
1138 if (
1139 !this.iElementNames.get(this.iElementNames.size() - 1).equals(this.iElementName.toUpperCase())
1140 ) throw new XMLPullParserException(
1141 this,
1142 "The content of elements must consist of well-formed character data or markup."
1143 );
1144
1145 this.iElementNames.remove(this.iElementNames.size() - 1);
1146
1147 ch = skipOptionalSpaces(ch);
1148 if (ch != '>') throw new XMLPullParserException(
1149 this,
1150 "\'=\' was expected, but \'" + escape(ch) + "\' was found instead"
1151 );
1152
1153 if (this.iElementNames.size() == 0) this.iSeenEpilog = true;
1154 }
1155
1156 protected int parsePI() throws IOException {
1157 char ch;
1158 ch = (char) getNextChar();
1159 boolean dashFound = false;
1160 do {
1161 ch = (char) getNextCharCheckingEOF();
1162 if (ch == '?') {
1163 dashFound = true;
1164 } else if (ch == '>' && dashFound) {
1165 break;
1166 } else {
1167 dashFound = false;
1168 }
1169 if (ch == (char) -1) throw new XMLPullParserException(
1170 "XML document structures must start and end within the same entity."
1171 );
1172 } while (true);
1173
1174 return -1;
1175 }
1176
1177 protected int parseReference() throws IOException {
1178 char ch1 = (char) getNextChar();
1179 if (ch1 == '#') {
1180 ch1 = (char) getNextChar();
1181 if (ch1 == 'x') {
1182 int value = 0;
1183 do {
1184 ch1 = (char) getNextChar();
1185 if (ch1 >= '0' && ch1 <= '9') value = value * 16 + (ch1 - '0'); else if (
1186 ch1 >= 'A' && ch1 <= 'F' || ch1 >= 'a' && ch1 <= 'f'
1187 ) value = value * 16 + (Character.toUpperCase(ch1) - 'A' + 10); else if (
1188 ch1 == ';'
1189 ) break; else throw new XMLPullParserException(
1190 this,
1191 "invalid character while parsing hex encoded number " + escape(ch1)
1192 );
1193 } while (true);
1194 return (char) value;
1195 }
1196 int value = 0;
1197 if (ch1 >= '0' && ch1 <= '9') {
1198 do {
1199 if (ch1 >= '0' && ch1 <= '9') {
1200 value = value * 10 + (ch1 - '0');
1201 ch1 = (char) getNextChar();
1202 } else if (ch1 == ';') break; else throw new XMLPullParserException(
1203 this,
1204 "invalid character while parsing decimal encoded number: " + escape(ch1)
1205 );
1206 } while (true);
1207 return (char) value;
1208 }
1209 throw new XMLPullParserException(this, "invalid number format");
1210 }
1211 int startPos = this.iCurrentPosition - 1;
1212 if (isValidStartElementNameChar(ch1)) {
1213 do {
1214 ch1 = (char) getNextChar();
1215 if (ch1 == ';') break;
1216 if (!isValidElementNameChar(ch1)) throw new XMLPullParserException(
1217 "invalid reference character " + escape(ch1)
1218 );
1219 } while (true);
1220 } else {
1221 throw new XMLPullParserException(this, "expected valid name start character for value reference");
1222 }
1223 goBack();
1224 ch1 = this.iBufferChar[startPos];
1225 char ch2 = this.iBufferChar[startPos + 1];
1226 char ch3 = this.iBufferChar[startPos + 2];
1227
1228 if (ch1 == 'l' && ch2 == 't' && ch3 == ';') {
1229 return '<';
1230 } else if (ch1 == 'g' && ch2 == 't' && ch3 == ';') {
1231 return '>';
1232 } else {
1233 char ch4 = this.iBufferChar[startPos + 3];
1234 if (ch1 == 'a' && ch2 == 'm' && ch3 == 'p' && ch4 == ';') {
1235 return '&';
1236 }
1237 char ch5 = this.iBufferChar[startPos + 4];
1238 if (ch1 == 'a' && ch2 == 'p' && ch3 == 'o' && ch4 == 's' && ch5 == ';') {
1239 return '\'';
1240 } else if (ch1 == 'q' && ch2 == 'u' && ch3 == 'o' && ch4 == 't' && ch5 == ';') {
1241 return '\"';
1242 } else {
1243
1244 }
1245 }
1246 return -1;
1247 }
1248
1249 protected int parseStartElement(char ch) throws IOException {
1250 int startElementName;
1251 int endElementName;
1252
1253 resetAttributes();
1254
1255 startElementName = this.iCurrentPosition - 1;
1256
1257 do {
1258
1259
1260
1261 ch = (char) getNextChar();
1262 } while (isValidElementNameChar(ch));
1263
1264 endElementName = this.iCurrentPosition;
1265
1266
1267
1268
1269 this.iElementName = new String(this.iBufferChar, startElementName, endElementName - startElementName - 1);
1270
1271
1272
1273
1274
1275 this.iElementNames.add(this.iElementName.toUpperCase());
1276
1277 do {
1278 ch = skipOptionalSpaces(ch);
1279 if (ch == '>') {
1280 break;
1281 } else if (ch == '/') {
1282 ch = (char) getNextChar();
1283 if (ch != '>') {
1284 throw new XMLPullParserException(this, "\'=\' was expected, but \'" + escape(ch) + "\' was found instead");
1285 }
1286 this.iClosingElementNamePending = true;
1287 } else if (isValidStartElementNameChar(ch)) {
1288 parseAttribute(ch);
1289 ch = (char) getNextChar();
1290 } else throw new XMLPullParserException(
1291 this,
1292 "Element type \"CIM\" must be followed by either attribute specifications, \">\" or \"/>\"."
1293 );
1294 } while (true);
1295 return -1;
1296 }
1297
1298 protected void parseUnknown() throws IOException {
1299 char ch;
1300 do {
1301 ch = (char) getNextChar();
1302 if (ch == '<') throw new XMLPullParserException("\'>\' was expected, but \'<\' was found instead.");
1303 } while (ch != '>');
1304 }
1305
1306 protected void resetAttributes() {
1307 this.iTotalAttributes = 0;
1308
1309
1310 this.iAttributeNames.clear();
1311 this.iAttributeValues.clear();
1312
1313 }
1314
1315 protected char skipOptionalSpaces(char ch) throws IOException {
1316 while (isSpace(ch)) {
1317 ch = (char) getNextChar();
1318 }
1319 return ch;
1320 }
1321
1322 protected char skipRequiredSpaces(char ch) throws IOException {
1323 if (!isSpace(ch)) throw new XMLPullParserException(this, "space expected");
1324 do {
1325 ch = (char) getNextChar();
1326 } while (isSpace(ch));
1327 return ch;
1328 }
1329 }