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) {