wsdlpull 1.23
Loading...
Searching...
No Matches
XmlPullParser.cpp
Go to the documentation of this file.
1/* Copyright (c) 2005,2007 Vivek Krishna
2 * Based on kxml2 by Stefan Haustein, Oberhausen, Rhld., Germany
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 * IN THE SOFTWARE. */
20
23#include "xmlpull/XmlUtils.h"
24//
25#include <cstring>
26
27
29 :unexpected_eof ("Unexpected EOF"),
30 illegal_type ("wrong Event Type"),
31 nspStack (16),
32 elementStack (16),
33 attributes (16),
34 reader (is)
35{
36 initBuf ();
37 commonInit ();
38}
39
40
42 :unexpected_eof ("Unexpected EOF"),
43 illegal_type ("wrong Event Type"),
44 nspStack (16),
45 elementStack (16),
46 attributes (16),
47 reader (std::cin)
48{
49 initBuf ();
50 commonInit ();
51}
52
53
54void
55XmlPullParser::initBuf ()
56{
57 srcBuf = new char[8192];
58 srcBuflength = 8192;
59 txtBuf = new char[256];
60 txtBufSize = 256;
61 nspCounts = new int[8];
62 nspSize = 8;
63}
64
65
66//does common initializations
67void
68XmlPullParser::commonInit ()
69{
70 line = 1;
71 column = 0;
72 type = START_DOCUMENT;
73 name = "";
74 Ns = "";
75 degenerated = false;
76 attributeCount = -1;
77 encoding = "";
78 version = "";
79 standalone = false;
80 unresolved = false;
81 LEGACY = 999;
82 XML_DECL = 998;
83 srcPos = 0;
84 srcCount = 0;
85 peekCount = 0;
86 depth = 0;
87 relaxed = false;
88 skipNextTag=false;
89 entityMap["apos"] = "'";
90 entityMap["gt"] = ">";
91 entityMap["lt"] = "<";
92 entityMap["quot"] = "\"";
93 entityMap["amp"] = "&";
94 for (int i = 0; i < nspSize; i++)
95 nspCounts[i] = 0;
96}
97
98
100{
101 delete [] srcBuf;
102 delete [] txtBuf;
103 delete [] nspCounts;
104}
105
106
107std::string
108XmlPullParser::state (int eventType)
109{
110 switch (eventType)
111 {
112 case 0:
113 return "START_DOCUMENT";
114 case 1:
115 return "END_DOCUMENT";
116 case 2:
117 return "START_TAG";
118 case 3:
119 return "END_TAG";
120 case 4:
121 return "TEXT";
122 case 5:
123 return "CDSECT";
124 case 6:
125 return "ENTITY_REF";
126 case 7:
127 return "IGNORABLE_WHITESPACE";
128 case 8:
129 return "PROCESSING_INSTRUCTION";
130 case 9:
131 return "COMMENT";
132 case 10:
133 return "DOCDECL";
134 default:
135 return "Illegal state";
136 break;
137 }
138 return "";
139}
140
141
142bool XmlPullParser::isProp (std::string n1, bool prop, std::string n2)
143{
144 if (n1.find ("http://xmlpull.org/v1/doc/") != 0)
145 return false;
146 if (prop)
147 return (n1.substr (42) == n2);
148 else
149 return (n1.substr (40) == n2);
150}
151
152
153bool XmlPullParser::adjustNsp ()
154{
155 bool
156 any = false;
157 for (int i = 0; i < attributeCount << 2; i += 4)
158
159 {
160 std::string
161 attrName = attributes[i + 2];
162 int
163 cut = attrName.find (":");
164 std::string
165 prefx;
166 // Creating a variable named 'prefix' generates a warning about hiding the member, so I changed it to 'prefx'. -KEC
167 if (cut != -1)
168
169 {
170 prefx = attrName.substr (0, cut);
171 attrName = attrName.substr (cut + 1);
172 }
173
174 else if (attrName == "xmlns")
175
176 {
177 prefx = attrName;
178 attrName = "";
179 }
180
181 else
182 continue;
183 if (prefx != "xmlns")
184 {
185 any = true;
186 }
187 else
188 {
189 unsigned int j = (nspCounts[depth]++) << 1;
190
191 //nspStack = ensureCapacity(nspStack, j + 2);
192 if (nspStack.size () <= j + 2)
193 nspStack.resize (j + 2 + RESIZE_BUFFER);
194 nspStack[j] = attrName;
195 nspStack[j + 1] = attributes[i + 3];
196 if (!attrName.empty () && attributes[i + 3] == "")
197 exception ("illegal empty namespace");
198
199 //vivek,array copy??
200 int to = ((--attributeCount) << 2) - i;
201 for (int p = 1; p <= to; p++)
202 attributes[i + p - 1] = attributes[i + 4 + p - 1];
203 i -= 4;
204 }
205 }
206 if (any)
207
208 {
209 for (int i = (attributeCount << 2) - 4; i >= 0; i -= 4)
210
211 {
212 std::string
213 attrName = attributes[i + 2];
214 int
215 cut = attrName.find (":");
216 if (cut == 0 && !relaxed)
217 exception ("illegal attribute name: " + attrName);
218
219 else if (cut != -1)
220
221 {
222 std::string
223 attrPrefix = attrName.substr (0, cut);
224 attrName = attrName.substr (cut + 1);
225 std::string
226 attrNs = getNamespace (attrPrefix);
227 if (attrNs.empty () && !relaxed)
228 exception ("Undefined Prefix: " + attrPrefix + " in ");
229 attributes[i] = attrNs;
230 attributes[i + 1] = attrPrefix;
231 attributes[i + 2] = attrName;
232 if (!relaxed)
233
234 {
235 for (int j = (attributeCount << 2) - 4; j > i; j -= 4)
236 if (attrName == attributes[j + 2]
237 && attrNs == attributes[j])
238 exception ("Duplicate Attribute: {"
239 + attrNs + "}" + attrName);
240 }
241 }
242 }
243 }
244 int cut = name.find (":");
245 if (cut == 0 && !relaxed)
246 exception ("illegal tag name: " + name);
247
248 else if (cut != -1)
249 {
250 prefix = name.substr (0, cut);
251 name = name.substr (cut + 1);
252 }
253 Ns = getNamespace (prefix);
254 if (Ns.empty ())
255
256 {
257 if (!prefix.empty () && !relaxed)
258 exception ("undefined prefix: " + prefix);
259 Ns = NO_NAMESPACE;
260 }
261 return any;
262}
263
264
265void
266XmlPullParser::exception (std::string desc)
267{
268 XmlPullParserException e (desc, state (type), line, column);
269 throw e;
270}
271
272
276void
277XmlPullParser::nextImpl ()
278{
279 if (type == END_TAG)
280 depth--;
281 while (true)
282 {
283 attributeCount = -1;
284 if (degenerated)
285
286 {
287 degenerated = false;
288 type = END_TAG;
289 return;
290 }
291 prefix = "";
292 name = "";
293 Ns = "";
294 text = "";
295 type = peekType ();
296 switch (type)
297 {
298 case ENTITY_REF:
299 pushEntity ();
300 return;
301 case START_TAG:
302 parseStartTag (false);
303 return;
304 case END_TAG:
305 parseEndTag ();
306 return;
307 case END_DOCUMENT:
308 return;
309 case TEXT:
310 pushText ('<', !token);
311 if (depth == 0)
312
313 {
314 if (isWspace)
316
317 // make exception switchable for instances.chg... !!!!
318 // else
319 // exception ("text '"+getText ()+"' not allowed outside root element");
320 }
321 return;
322 default:
323 type = parseLegacy (token);
324 if (type != XML_DECL)
325 return;
326 }
327 }
328}
329
330
331int
332XmlPullParser::parseLegacy (bool bpush)
333{
334 std::string req = "";
335 int term;
336 int result;
337 int prev = 0;
338 read (); // <
339 int c = read ();
340 if (c == '?')
341
342 {
343 if ((peekbuf (0) == 'x' || peekbuf (0) == 'X')
344 && (peekbuf (1) == 'm' || peekbuf (1) == 'M'))
345
346 {
347 if (bpush)
348
349 {
350 push (peekbuf (0));
351 push (peekbuf (1));
352 }
353 read ();
354 read ();
355 if ((peekbuf (0) == 'l' || peekbuf (0) == 'L')
356 && peekbuf (1) <= ' ')
357
358 {
359 if (line != 1 || column > 4)
360 exception ("PI must not start with xml");
361 parseStartTag (true);
362 if (attributeCount < 1 || "version" != attributes[2])
363 exception ("version expected");
364 version = attributes[3];
365 int pos = 1;
366 if (pos < attributeCount && "encoding" == attributes[2 + 4])
367
368 {
369 encoding = attributes[3 + 4];
370 pos++;
371 }
372 if (pos < attributeCount
373 && "standalone" == attributes[4 * pos + 2])
374
375 {
376 std::string st = attributes[3 + 4 * pos];
377 if ("yes" == st)
378 standalone = true;
379
380 else if ("no" == st)
381 standalone = false;
382
383 else
384 exception ("illegal standalone value: " + st);
385 pos++;
386 }
387 if (pos != attributeCount)
388 exception ("illegal xmldecl");
389 isWspace = true;
390 txtPos = 0;
391 return XML_DECL;
392 }
393 }
394
395 /* int c0 = read ();
396 int c1 = read ();
397 int */
398 term = '?';
399 result = PROCESSING_INSTRUCTION;
400 }
401
402 else if (c == '!')
403
404 {
405 if (peekbuf (0) == '-')
406
407 {
408 result = COMMENT;
409 req = "--";
410 term = '-';
411 }
412
413 else if (peekbuf (0) == '[')
414
415 {
416 result = CDSECT;
417 req = "[CDATA[";
418 term = ']';
419 bpush = true;
420 }
421
422 else
423
424 {
425 result = DOCDECL;
426 req = "DOCTYPE";
427 term = -1;
428 }
429 }
430
431 else
432
433 {
434 exception ("illegal: <" + c);
435 return -1;
436 }
437 for (unsigned int i = 0; i < req.length (); i++)
438 read (req.at (i));
439 if (result == DOCDECL)
440 parseDoctype (bpush);
441
442 else
443
444 {
445 while (true)
446
447 {
448 c = read ();
449 if (c == -1)
450 exception (unexpected_eof);
451 if (bpush)
452 push (c);
453 if ((term == '?' || c == term)
454 && peekbuf (0) == term && peekbuf (1) == '>')
455 break;
456 prev = c;
457 }
458 if (term == '-' && prev == '-' && !relaxed)
459 exception ("illegal comment delimiter: --->");
460 read ();
461 read ();
462 if (bpush && term != '?')
463 txtPos--;
464 }
465 return result;
466}
467
468
470void
471XmlPullParser::parseDoctype (bool bpush)
472{
473 int nesting = 1;
474 bool quoted = false;
475
476 // read();
477 while (true)
478
479 {
480 int i = read ();
481 switch (i)
482
483 {
484 case -1:
485 exception (unexpected_eof);
486 case '\'':
487 quoted = !quoted;
488 break;
489 case '<':
490 if (!quoted)
491 nesting++;
492 break;
493 case '>':
494 if (!quoted)
495
496 {
497 if ((--nesting) == 0)
498 return;
499 }
500 break;
501 }
502 if (bpush)
503 push (i);
504 }
505}
506
507
508/* precondition: &lt;/ consumed */
509void
510XmlPullParser::parseEndTag ()
511{
512 read (); // '<'
513 read (); // '/'
514 name = readName ();
515 skip ();
516 read ('>');
517 int sp = (depth - 1) << 2;
518 if (!relaxed)
519
520 {
521 if (depth == 0)
522 exception ("element stack empty");
523 if (name != elementStack[sp + 3])
524 exception ("expected: " + elementStack[sp + 3]);
525 }
526
527 else if (depth == 0 || name != elementStack[sp + 3])
528 return;
529 Ns = elementStack[sp];
530 prefix = elementStack[sp + 1];
531 name = elementStack[sp + 2];
532}
533
534
535int
536XmlPullParser::peekType ()
537{
538 switch (peekbuf (0))
539
540 {
541 case -1:
542 return END_DOCUMENT;
543 case '&':
544 return ENTITY_REF;
545 case '<':
546 switch (peekbuf (1))
547
548 {
549 case '/':
550 return END_TAG;
551 case '?':
552 case '!':
553 return LEGACY;
554 default:
555 return START_TAG;
556 }
557 default:
558 return TEXT;
559 }
560}
561
562
563std::string XmlPullParser::get (int pos)
564{
565 std::string
566 tmp (txtBuf);
567 return tmp.substr (pos, txtPos - pos);
568}
569
570
571void
572XmlPullParser::push (int c)
573{
574 isWspace &= c <= ' ';
575 if (txtPos >= txtBufSize - 1)
576
577 {
578 char *bigger = new char[txtBufSize = txtPos * 4 / 3 + 4];
579 memcpy (bigger, txtBuf, txtPos);
580 delete[] txtBuf;
581 txtBuf = bigger;
582 }
583 txtBuf[txtPos++] = (char) c;
584 txtBuf[txtPos] = 0;
585}
586
587
589void
590XmlPullParser::parseStartTag (bool xmldecl)
591{
592 if (!xmldecl)
593 read ();
594 name = readName ();
595 attributeCount = 0;
596 while (true)
597
598 {
599 skip ();
600 int c = peekbuf (0);
601 if (xmldecl)
602
603 {
604 if (c == '?')
605
606 {
607 read ();
608 read ('>');
609 return;
610 }
611 }
612
613 else
614
615 {
616 if (c == '/')
617
618 {
619 degenerated = true;
620 read ();
621 skip ();
622 read ('>');
623 break;
624 }
625 if (c == '>' && !xmldecl)
626
627 {
628 read ();
629 break;
630 }
631 }
632 if (c == -1)
633 exception (unexpected_eof);
634 std::string attrName = readName ();
635 if (attrName.empty ())
636 exception ("attr name expected");
637 skip ();
638 read ('=');
639 skip ();
640 int delimiter = read ();
641 if (delimiter != '\'' && delimiter != '"')
642
643 {
644 if (!relaxed)
645 exception ("<"
646 + name + ">: invalid delimiter: " + (char) delimiter);
647 delimiter = ' ';
648 }
649 unsigned int i = (attributeCount++) << 2;
650
651 //attributes = ensureCapacity(attributes, i + 4);
652 if (attributes.size () <= i + 4)
653 attributes.resize (i + 4 + RESIZE_BUFFER);
654 attributes[i++] = "";
655 attributes[i++] = "";
656 attributes[i++] = attrName;
657 int p = txtPos;
658 pushText (delimiter, true);
659 attributes[i] = get (p);
660 txtPos = p;
661 if (delimiter != ' ')
662 read (); // skip endquote
663 }
664 unsigned int sp = depth++ << 2;
665
666 //elementStack = ensureCapacity(elementStack, sp + 4,elementStackSize);
667 if (elementStack.size () <= sp + 4)
668 elementStack.resize (sp + 4 + RESIZE_BUFFER);
669 elementStack[sp + 3] = name;
670
671 /* vivek ,avoided the increment array logic..fix later*/
672 if (depth >= nspSize)
673
674 {
675 int *bigger = new int[nspSize + 4];
676 int i = 0;
677 for (i = 0; i < nspSize; i++)
678 bigger[i] = nspCounts[i];
679 for (i = nspSize; i < nspSize + 4; i++)
680 bigger[i] = 0;
681 delete [] nspCounts;
682 nspCounts = bigger;
683 nspSize += 4;
684 }
685 nspCounts[depth] = nspCounts[depth - 1];
686 for (int i = attributeCount - 1; i > 0; i--)
687
688 {
689 for (int j = 0; j < i; j++)
690
691 {
692 if (getAttributeName (i) == getAttributeName (j))
693 exception ("Duplicate Attribute: " + getAttributeName (i));
694 }
695 }
696 if (processNsp)
697 adjustNsp ();
698
699 else
700 Ns = "";
701 elementStack[sp] = Ns;
702 elementStack[sp + 1] = prefix;
703 elementStack[sp + 2] = name;
704}
705
706
709void
710XmlPullParser::pushEntity ()
711{
712 read (); // &
713 int pos = txtPos;
714 while (true)
715
716 {
717 int c = read ();
718 if (c == ';')
719 break;
720 if (relaxed && (c == '<' || c == '&' || c <= ' '))
721
722 {
723 if (c != -1)
724 push (c);
725 return;
726 }
727 if (c == -1)
728 exception (unexpected_eof);
729 push (c);
730 }
731 std::string code = get (pos);
732 txtPos = pos;
733 if (token && type == ENTITY_REF)
734 name = code;
735 if (code[0] == '#')
736
737 {
738 int c = (code[1] == 'x' ? XmlUtils::parseInt (code.substr (2),16)
739 : XmlUtils::parseInt (code.substr (1)));
740 push (c);
741 return;
742 }
743 std::string result = (std::string) entityMap[code];
744 unresolved = result == "";
745 if (unresolved)
746
747 {
748 if (!token)
749 exception ("unresolved: &" + code + ";");
750 }
751
752 else
753
754 {
755 for (unsigned int i = 0; i < result.length (); i++)
756 push (result.at (i));
757 }
758}
759
760
766void
767XmlPullParser::pushText (int delimiter, bool resolveEntities)
768{
769 int next = peekbuf (0);
770 while (next != -1 && next != delimiter) // covers eof, '<', '"'
771 {
772 if (delimiter == ' ')
773 if (next <= ' ' || next == '>')
774 break;
775 if (next == '&')
776
777 {
778 if (!resolveEntities)
779 break;
780 pushEntity ();
781 }
782
783 else if (next == '\n' && type == START_TAG)
784
785 {
786 read ();
787 push (' ');
788 }
789
790 else
791 push (read ());
792 next = peekbuf (0);
793 }
794}
795
796
797void
798XmlPullParser::read (char c)
799{
800 int a = read ();
801 std::string sa (1, (char) a), sc (1, c);
802 if (a != c)
803 exception ("expected: '" + sc + "' actual: '" + sa + "'");
804}
805
806
807int
808XmlPullParser::read ()
809{
810 int result;
811 if (peekCount == 0)
812 result = peekbuf (0);
813
814 else
815
816 {
817 result = peek[0];
818 peek[0] = peek[1];
819 }
820 peekCount--;
821 column++;
822 if (result == '\n')
823
824 {
825 line++;
826 column = 1;
827 }
828 return result;
829}
830
831
833int
834XmlPullParser::peekbuf (int pos)
835{
836 while (pos >= peekCount)
837
838 {
839 int nw;
840 if (srcBuflength <= 1)
841 nw = reader.get ();
842
843 else if (srcPos < srcCount)
844 nw = srcBuf[srcPos++];
845
846 else
847
848 {
849 srcCount = reader.read (srcBuf, srcBuflength).gcount ();
850 if (srcCount <= 0)
851 nw = -1;
852
853 else
854 nw = srcBuf[0];
855 srcPos = 1;
856 }
857 if (nw == '\r')
858
859 {
860 wasCR = true;
861 peek[peekCount++] = '\n';
862 }
863
864 else
865
866 {
867 if (nw == '\n')
868
869 {
870 if (!wasCR)
871 peek[peekCount++] = '\n';
872 }
873
874 else
875 peek[peekCount++] = nw;
876 wasCR = false;
877 }
878 }
879 return peek[pos];
880}
881
882
883std::string XmlPullParser::readName ()
884{
885 int pos = txtPos;
886 int c = peekbuf (0);
887 if ((c < 'a' || c > 'z')
888 && (c < 'A' || c > 'Z') && c != '_' && c != ':' && c < 0x0c0)
889 exception ("name expected");
890
891 do
892
893 {
894 push (read ());
895 c = peekbuf (0);
896 }
897 while ((c >= 'a' && c <= 'z')
898 || (c >= 'A' && c <= 'Z')
899 || (c >= '0' && c <= '9')
900 || c == '_' || c == '-' || c == ':' || c == '.' || c >= 0x0b7);
901 std::string
902 result = get (pos);
903 txtPos = pos;
904 return result;
905}
906
907
908void
909XmlPullParser::skip ()
910{
911 while (true)
912
913 {
914 int c = peekbuf (0);
915 if (c > ' ' || c == -1)
916 break;
917 read ();
918 }
919}
920
921
922//--------------- public part starts here... ---------------
923bool XmlPullParser::getFeature (std::string feature)
924{
925 if (FEATURE_PROCESS_NAMESPACES == feature)
926 return processNsp;
927
928 else if (isProp (feature, false, "relaxed"))
929 return relaxed;
930
931 else
932 return false;
933}
934
935
937{
938 return encoding;
939}
940
941
942void
943XmlPullParser::defineEntityReplacementText (std::string entity, std::string value)
944{
945 if (entityMap.empty ())
946 exception ("entity replacement text must be defined after setInput!");
947 entityMap[entity] = value;
948}
949
950
951int
953{
954 if (d > depth)
955 exception ("IndexOutOfBoundsException");;
956 return nspCounts[d];
957}
958
959
961{
962 return nspStack[pos << 1];
963}
964
965
967{
968 return nspStack[(pos << 1) + 1];
969}
970
971
972std::string XmlPullParser::getNamespace (std::string prefx)
973{
974 if ("xml" == prefx)
975 return "http://www.w3.org/XML/1998/namespace";
976 if ("xmlns" == prefx)
977 return "http://www.w3.org/2000/xmlns/";
978 for (int i = (getNamespaceCount (depth) << 1) - 2; i >= 0; i -= 2)
979
980 {
981 if (prefx.empty ())
982
983 {
984
985 //cout<<nspStack[i]<<nspStack[i+1]<<endl;
986 if (nspStack[i].empty ())
987 return nspStack[i + 1];
988 }
989
990 else if (prefx == nspStack[i])
991 return nspStack[i + 1];
992 }
993 return "";
994}
995
996
997int
999{
1000 return depth;
1001}
1002
1003
1004std::string
1006{
1007 std::ostringstream buf (std::ios::ate);
1008 //vivek,replace 11 by the number of event types
1009 buf << (type < 11 ? state (type) : "Unknown Event");
1010 buf << " ";
1011 if (type == START_TAG || type == END_TAG)
1012
1013 {
1014 if (degenerated)
1015 buf << "(empty) ";
1016 buf << "<";
1017 if (type == END_TAG)
1018 buf << "/";
1019 if (!prefix.empty ())
1020 buf << "{" << Ns << "}" << prefix << ":";
1021 buf << name;
1022 int
1023 cnt = attributeCount << 2;
1024 for (int i = 0; i < cnt; i += 4)
1025
1026 {
1027 buf << " ";
1028 if (!attributes[i + 1].empty ())
1029 buf << "{" << attributes[i] << "}" << attributes[i + 1] << ":";
1030 buf << attributes[i + 2] << "='" << attributes[i + 3] << "'";
1031 }
1032 buf << ">";
1033 }
1034
1035 else if (type == IGNORABLE_WHITESPACE);
1036
1037 else if (type != TEXT)
1038 buf << getText ();
1039
1040 else if (isWspace)
1041 buf << "(whitespace)";
1042
1043 else
1044
1045 {
1046 std::string
1047 txt = getText ();
1048 if (txt.length () > 16)
1049 txt = txt.substr (0, 16) + "...";
1050 buf << txt;
1051 }
1052 buf << " @" << line << ":" << column;
1053 return buf.str (); //replace buf with an ostream
1054}
1055
1056
1058{
1059 if (type != TEXT && type != IGNORABLE_WHITESPACE && type != CDSECT)
1060 exception (illegal_type);
1061 return isWspace;
1062}
1063
1064
1066{
1067 return type < TEXT || (type == ENTITY_REF && unresolved) ? "" : get (0);
1068}
1069
1070
1071const char *
1073{
1074 if (type >= TEXT)
1075
1076 {
1077 if (type == ENTITY_REF)
1078
1079 {
1080 poslen[0] = 0;
1081 poslen[1] = name.length ();
1082 return name.c_str (); //return name.toCharArray();
1083 }
1084 poslen[0] = 0;
1085 poslen[1] = txtPos;
1086 return txtBuf;
1087 }
1088 poslen[0] = -1;
1089 poslen[1] = -1;
1090 return 0;
1091}
1092
1093
1095{
1096 if (type != START_TAG)
1097 exception (illegal_type);
1098 return degenerated;
1099}
1100
1101
1103{
1104 if (index >= attributeCount)
1105 exception ("IndexOutOfBoundsException()");
1106 return attributes[index << 2];
1107}
1108
1109
1110std::string XmlPullParser::getAttributeName (int index)
1111{
1112 if (index >= attributeCount)
1113 exception ("IndexOutOfBoundsException()");
1114 return attributes[(index << 2) + 2];
1115}
1116
1117
1119{
1120 if (index >= attributeCount)
1121 exception ("IndexOutOfBoundsException()");
1122 return attributes[(index << 2) + 1];
1123}
1124
1125
1127{
1128 if (index >= attributeCount)
1129 exception ("IndexOutOfBoundsException()");
1130 return attributes[(index << 2) + 3];
1131}
1132
1133
1134std::string XmlPullParser::getAttributeValue (std::string ns, std::string nam)
1135{
1136 for (int i = (attributeCount << 2) - 4; i >= 0; i -= 4)
1137
1138 {
1139 if (attributes[i + 2] == nam && (ns.empty () || attributes[i] == ns))
1140 return attributes[i + 3];
1141 }
1142 return "";
1143}
1144
1145
1146int
1148{
1149 txtPos = 0;
1150 isWspace = true;
1151 int minType = 9999;
1152 token = false;
1153
1154 do
1155
1156 {
1157 nextImpl ();
1158 if (type < minType)
1159 minType = type;
1160
1161// if (curr <= TEXT) type = curr;
1162 }
1163 while (minType > CDSECT // ignorable
1164 || (minType >= TEXT && peekType () >= TEXT));
1165 type = minType;
1166 if (type > TEXT)
1167 type = TEXT;
1168 return type;
1169}
1170
1171
1172int
1174{
1175 isWspace = true;
1176 txtPos = 0;
1177 token = true;
1178 nextImpl ();
1179 return type;
1180}
1181
1182void
1184{
1185 skipNextTag=true;
1186}
1187
1188//----------------------------------------------------------------------
1189// utility methods to make XML parsing easier ...
1190int
1192{
1193 if(skipNextTag){
1194 skipNextTag = false;
1195 return type;
1196 }
1197 next ();
1198 if (type == TEXT && isWspace)
1199 next ();
1200 if (type != END_TAG && type != START_TAG && type != END_DOCUMENT)
1201 exception ("unexpected type");
1202 return type;
1203}
1204
1205
1206void
1207XmlPullParser::require (int Type, std::string ns, std::string nam)
1208{
1209 if (Type != type || (!ns.empty () && ns != getNamespace ())
1210 || (!nam.empty () && nam != getName ()))
1211 exception ("expected: " + state (Type) + " {" + ns + "}" + nam);
1212}
1213
1214
1216{
1217 if (type != START_TAG)
1218 exception ("precondition: START_TAG");
1219 next ();
1220 std::string
1221 result;
1222 if (type == TEXT)
1223
1224 {
1225 result = getText ();
1226 next ();
1227 }
1228
1229 else
1230 result = "";
1231 if (type != END_TAG)
1232 exception ("END_TAG expected");
1233 return result;
1234}
1235
1236
1237void
1238XmlPullParser::setFeature (std::string feature, bool value)
1239{
1240 if (FEATURE_PROCESS_NAMESPACES == feature)
1241 processNsp = value;
1242
1243 else if (isProp (feature, false, "relaxed"))
1244 relaxed = value;
1245
1246 else
1247 exception ("unsupported feature: " + feature);
1248}
1249
1250/*
1251void
1252XmlPullParser::setProperty(std::string property, std::string value)
1253{
1254 if(isProp(property, true, "location"))
1255 {
1256 location = value;
1257 }
1258 else
1259 exception ("unsupported property: " + property);
1260}
1261*/
1262
1268// Implementation copied from Alek's mail...
1269
1270void
1272 require(START_TAG, "", "");
1273 int level = 1;
1274 while (level > 0) {
1275 int eventType = next();
1276 if (eventType == END_TAG) {
1277 --level;
1278 }
1279 else if (eventType == START_TAG) {
1280 ++level;
1281 }
1282 }
1283}
1284
const int RESIZE_BUFFER
#define FEATURE_PROCESS_NAMESPACES
#define NO_NAMESPACE
std::string getNamespace()
std::string nextText()
const char * getTextCharacters(int *poslen)
bool getFeature(std::string feature)
void require(int type, std::string ns, std::string name)
std::string getName()
std::string getInputEncoding()
std::string getAttributeValue(int index)
std::string getPositionDescription()
std::string getText()
std::string getNamespaceUri(int pos)
std::string getAttributeNamespace(int index)
std::string getAttributePrefix(int index)
int getNamespaceCount(int depth)
std::string getAttributeName(int index)
void defineEntityReplacementText(std::string entity, std::string value)
std::string getNamespacePrefix(int pos)
void setFeature(std::string feature, bool value)
int parseInt(std::string s, int radix=10)
Definition XmlUtils.cpp:57