29 :unexpected_eof (
"Unexpected EOF"),
30 illegal_type (
"wrong Event Type"),
42 :unexpected_eof (
"Unexpected EOF"),
43 illegal_type (
"wrong Event Type"),
55 XmlPullParser::initBuf ()
57 srcBuf =
new char[8192];
59 txtBuf =
new char[256];
61 nspCounts =
new int[8];
68 XmlPullParser::commonInit ()
89 entityMap[
"apos"] =
"'";
90 entityMap[
"gt"] =
">";
91 entityMap[
"lt"] =
"<";
92 entityMap[
"quot"] =
"\"";
93 entityMap[
"amp"] =
"&";
94 for (
int i = 0; i < nspSize; i++)
108 XmlPullParser::state (
int eventType)
113 return "START_DOCUMENT";
115 return "END_DOCUMENT";
127 return "IGNORABLE_WHITESPACE";
129 return "PROCESSING_INSTRUCTION";
135 return "Illegal state";
142 bool XmlPullParser::isProp (std::string n1,
bool prop, std::string n2)
144 if (n1.find (
"http://xmlpull.org/v1/doc/") != 0)
147 return (n1.substr (42) == n2);
149 return (n1.substr (40) == n2);
153 bool XmlPullParser::adjustNsp ()
157 for (
int i = 0; i < attributeCount << 2; i += 4)
161 attrName = attributes[i + 2];
163 cut = attrName.find (
":");
170 prefx = attrName.substr (0, cut);
171 attrName = attrName.substr (cut + 1);
174 else if (attrName ==
"xmlns")
183 if (prefx !=
"xmlns")
189 unsigned int j = (nspCounts[depth]++) << 1;
192 if (nspStack.size () <= j + 2)
194 nspStack[j] = attrName;
195 nspStack[j + 1] = attributes[i + 3];
196 if (!attrName.empty () && attributes[i + 3] ==
"")
197 exception (
"illegal empty namespace");
200 int to = ((--attributeCount) << 2) - i;
201 for (
int p = 1; p <= to; p++)
202 attributes[i + p - 1] = attributes[i + 4 + p - 1];
209 for (
int i = (attributeCount << 2) - 4; i >= 0; i -= 4)
213 attrName = attributes[i + 2];
215 cut = attrName.find (
":");
216 if (cut == 0 && !relaxed)
217 exception (
"illegal attribute name: " + attrName);
223 attrPrefix = attrName.substr (0, cut);
224 attrName = attrName.substr (cut + 1);
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;
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);
244 int cut = name.find (
":");
245 if (cut == 0 && !relaxed)
246 exception (
"illegal tag name: " + name);
250 prefix = name.substr (0, cut);
251 name = name.substr (cut + 1);
257 if (!prefix.empty () && !relaxed)
258 exception (
"undefined prefix: " + prefix);
266 XmlPullParser::exception (std::string desc)
277 XmlPullParser::nextImpl ()
302 parseStartTag (
false);
310 pushText (
'<', !token);
323 type = parseLegacy (token);
324 if (type != XML_DECL)
332 XmlPullParser::parseLegacy (
bool bpush)
334 std::string req =
"";
343 if ((peekbuf (0) ==
'x' || peekbuf (0) ==
'X')
344 && (peekbuf (1) ==
'm' || peekbuf (1) ==
'M'))
355 if ((peekbuf (0) ==
'l' || peekbuf (0) ==
'L')
356 && peekbuf (1) <=
' ')
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];
366 if (pos < attributeCount &&
"encoding" == attributes[2 + 4])
369 encoding = attributes[3 + 4];
372 if (pos < attributeCount
373 &&
"standalone" == attributes[4 * pos + 2])
376 std::string st = attributes[3 + 4 * pos];
384 exception (
"illegal standalone value: " + st);
387 if (pos != attributeCount)
388 exception (
"illegal xmldecl");
405 if (peekbuf (0) ==
'-')
413 else if (peekbuf (0) ==
'[')
434 exception (
"illegal: <" + c);
437 for (
unsigned int i = 0; i < req.length (); i++)
440 parseDoctype (bpush);
450 exception (unexpected_eof);
453 if ((term ==
'?' || c == term)
454 && peekbuf (0) == term && peekbuf (1) ==
'>')
458 if (term ==
'-' && prev ==
'-' && !relaxed)
459 exception (
"illegal comment delimiter: --->");
462 if (bpush && term !=
'?')
471 XmlPullParser::parseDoctype (
bool bpush)
485 exception (unexpected_eof);
497 if ((--nesting) == 0)
510 XmlPullParser::parseEndTag ()
517 int sp = (depth - 1) << 2;
522 exception (
"element stack empty");
523 if (name != elementStack[sp + 3])
524 exception (
"expected: " + elementStack[sp + 3]);
527 else if (depth == 0 || name != elementStack[sp + 3])
529 Ns = elementStack[sp];
530 prefix = elementStack[sp + 1];
531 name = elementStack[sp + 2];
536 XmlPullParser::peekType ()
563 std::string XmlPullParser::get (
int pos)
567 return tmp.substr (pos, txtPos - pos);
572 XmlPullParser::push (
int c)
574 isWspace &= c <=
' ';
575 if (txtPos >= txtBufSize - 1)
578 char *bigger =
new char[txtBufSize = txtPos * 4 / 3 + 4];
579 memcpy (bigger, txtBuf, txtPos);
583 txtBuf[txtPos++] = (char) c;
590 XmlPullParser::parseStartTag (
bool xmldecl)
625 if (c ==
'>' && !xmldecl)
633 exception (unexpected_eof);
634 std::string attrName = readName ();
635 if (attrName.empty ())
636 exception (
"attr name expected");
640 int delimiter = read ();
641 if (delimiter !=
'\'' && delimiter !=
'"')
646 + name +
">: invalid delimiter: " + (
char) delimiter);
649 unsigned int i = (attributeCount++) << 2;
652 if (attributes.size () <= i + 4)
654 attributes[i++] =
"";
655 attributes[i++] =
"";
656 attributes[i++] = attrName;
658 pushText (delimiter,
true);
659 attributes[i] =
get (p);
661 if (delimiter !=
' ')
664 unsigned int sp = depth++ << 2;
667 if (elementStack.size () <= sp + 4)
669 elementStack[sp + 3] = name;
672 if (depth >= nspSize)
675 int *bigger =
new int[nspSize + 4];
677 for (i = 0; i < nspSize; i++)
678 bigger[i] = nspCounts[i];
679 for (i = nspSize; i < nspSize + 4; i++)
685 nspCounts[depth] = nspCounts[depth - 1];
686 for (
int i = attributeCount - 1; i > 0; i--)
689 for (
int j = 0; j < i; j++)
701 elementStack[sp] = Ns;
702 elementStack[sp + 1] = prefix;
703 elementStack[sp + 2] = name;
710 XmlPullParser::pushEntity ()
720 if (relaxed && (c ==
'<' || c ==
'&' || c <=
' '))
728 exception (unexpected_eof);
731 std::string code =
get (pos);
743 std::string result = (std::string) entityMap[code];
744 unresolved = result ==
"";
749 exception (
"unresolved: &" + code +
";");
755 for (
unsigned int i = 0; i < result.length (); i++)
756 push (result.at (i));
767 XmlPullParser::pushText (
int delimiter,
bool resolveEntities)
769 int next = peekbuf (0);
770 while (next != -1 && next != delimiter)
772 if (delimiter ==
' ')
773 if (next <= ' ' || next == '>
') 778 if (!resolveEntities) 783 else if (next == '\n
' && type == START_TAG) 798 XmlPullParser::read (char c) 801 std::string sa (1, (char) a), sc (1, c); 803 exception ("expected: '" + sc + "' actual: '" + sa + "'"); 808 XmlPullParser::read () 812 result = peekbuf (0); 834 XmlPullParser::peekbuf (int pos) 836 while (pos >= peekCount) 840 if (srcBuflength <= 1) 843 else if (srcPos < srcCount) 844 nw = srcBuf[srcPos++]; 849 srcCount = reader.read (srcBuf, srcBuflength).gcount (); 861 peek[peekCount++] = '\n
'; 871 peek[peekCount++] = '\n
'; 875 peek[peekCount++] = nw; 883 std::string XmlPullParser::readName () 887 if ((c < 'a
' || c > 'z
') 888 && (c < 'A
' || c > 'Z
') && c != '_
' && c != ':
' && c < 0x0c0) 889 exception ("name expected"); 897 while ((c >= 'a
' && c <= 'z
') 898 || (c >= 'A
' && c <= 'Z
') 899 || (c >= '0
' && c <= '9
') 900 || c == '_
' || c == '-
' || c == ':
' || c == '.
' || c >= 0x0b7); 909 XmlPullParser::skip () 915 if (c > ' ' || c == -1) 922 //--------------- public part starts here... --------------- 923 bool XmlPullParser::getFeature (std::string feature) 925 if (FEATURE_PROCESS_NAMESPACES == feature) 928 else if (isProp (feature, false, "relaxed")) 936 std::string XmlPullParser::getInputEncoding () 943 XmlPullParser::defineEntityReplacementText (std::string entity, std::string value) 945 if (entityMap.empty ()) 946 exception ("entity replacement text must be defined after setInput!"); 947 entityMap[entity] = value; 952 XmlPullParser::getNamespaceCount (int d) 955 exception ("IndexOutOfBoundsException");; 960 std::string XmlPullParser::getNamespacePrefix (int pos) 962 return nspStack[pos << 1]; 966 std::string XmlPullParser::getNamespaceUri (int pos) 968 return nspStack[(pos << 1) + 1]; 972 std::string XmlPullParser::getNamespace (std::string 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) 985 //cout<<nspStack[i]<<nspStack[i+1]<<endl; 986 if (nspStack[i].empty ()) 987 return nspStack[i + 1]; 990 else if (prefx == nspStack[i]) 991 return nspStack[i + 1]; 998 XmlPullParser::getDepth () 1005 XmlPullParser::getPositionDescription () 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"); 1011 if (type == START_TAG || type == END_TAG) 1017 if (type == END_TAG) 1019 if (!prefix.empty ()) 1020 buf << "{" << Ns << "}" << prefix << ":"; 1023 cnt = attributeCount << 2; 1024 for (int i = 0; i < cnt; i += 4) 1028 if (!attributes[i + 1].empty ()) 1029 buf << "{" << attributes[i] << "}" << attributes[i + 1] << ":"; 1030 buf << attributes[i + 2] << "='" << attributes[i + 3] << "'"; 1035 else if (type == IGNORABLE_WHITESPACE); 1037 else if (type != TEXT) 1041 buf << "(whitespace)"; 1048 if (txt.length () > 16) 1049 txt = txt.substr (0, 16) + "..."; 1052 buf << " @" << line << ":" << column; 1053 return buf.str (); //replace buf with an ostream 1057 bool XmlPullParser::isWhitespace () 1059 if (type != TEXT && type != IGNORABLE_WHITESPACE && type != CDSECT) 1060 exception (illegal_type); 1065 std::string XmlPullParser::getText () 1067 return type < TEXT || (type == ENTITY_REF && unresolved) ? "" : get (0); 1072 XmlPullParser::getTextCharacters (int *poslen) 1077 if (type == ENTITY_REF) 1081 poslen[1] = name.length (); 1082 return name.c_str (); //return name.toCharArray(); 1094 bool XmlPullParser::isEmptyElementTag () 1096 if (type != START_TAG) 1097 exception (illegal_type); 1102 std::string XmlPullParser::getAttributeNamespace (int index) 1104 if (index >= attributeCount) 1105 exception ("IndexOutOfBoundsException()"); 1106 return attributes[index << 2]; 1110 std::string XmlPullParser::getAttributeName (int index) 1112 if (index >= attributeCount) 1113 exception ("IndexOutOfBoundsException()"); 1114 return attributes[(index << 2) + 2]; 1118 std::string XmlPullParser::getAttributePrefix (int index) 1120 if (index >= attributeCount) 1121 exception ("IndexOutOfBoundsException()"); 1122 return attributes[(index << 2) + 1]; 1126 std::string XmlPullParser::getAttributeValue (int index) 1128 if (index >= attributeCount) 1129 exception ("IndexOutOfBoundsException()"); 1130 return attributes[(index << 2) + 3]; 1134 std::string XmlPullParser::getAttributeValue (std::string ns, std::string nam) 1136 for (int i = (attributeCount << 2) - 4; i >= 0; i -= 4) 1139 if (attributes[i + 2] == nam && (ns.empty () || attributes[i] == ns)) 1140 return attributes[i + 3]; 1147 XmlPullParser::next () 1161 // if (curr <= TEXT) type = curr; 1163 while (minType > CDSECT // ignorable 1164 || (minType >= TEXT && peekType () >= TEXT)); 1173 XmlPullParser::nextToken () 1183 XmlPullParser::prevTag() 1188 //---------------------------------------------------------------------- 1189 // utility methods to make XML parsing easier ... 1191 XmlPullParser::nextTag () 1194 skipNextTag = false; 1198 if (type == TEXT && isWspace) 1200 if (type != END_TAG && type != START_TAG && type != END_DOCUMENT) 1201 exception ("unexpected type"); 1207 XmlPullParser::require (int Type, std::string ns, std::string nam) 1209 if (Type != type || (!ns.empty () && ns != getNamespace ()) 1210 || (!nam.empty () && nam != getName ())) 1211 exception ("expected: " + state (Type) + " {" + ns + "}" + nam); 1215 std::string XmlPullParser::nextText () 1217 if (type != START_TAG) 1218 exception ("precondition: START_TAG"); 1225 result = getText (); 1231 if (type != END_TAG) 1232 exception ("END_TAG expected"); 1238 XmlPullParser::setFeature (std::string feature, bool value) 1240 if (FEATURE_PROCESS_NAMESPACES == feature) 1243 else if (isProp (feature, false, "relaxed")) 1247 exception ("unsupported feature: " + feature); 1252 XmlPullParser::setProperty(std::string property, std::string value) 1254 if(isProp(property, true, "location")) 1259 exception ("unsupported property: " + property); 1268 // Implementation copied from Alek's mail...
1272 require(START_TAG,
"",
"");
1275 int eventType = next();
1276 if (eventType == END_TAG) {
1279 else if (eventType == START_TAG) {
std::string getAttributeName(int index)
std::string getNamespace()
int parseInt(std::string s, int radix=10)