29 :unexpected_eof (
"Unexpected EOF"),
30 illegal_type (
"wrong Event Type"),
42 :unexpected_eof (
"Unexpected EOF"),
43 illegal_type (
"wrong Event Type"),
55XmlPullParser::initBuf ()
57 srcBuf =
new char[8192];
59 txtBuf =
new char[256];
61 nspCounts =
new int[8];
68XmlPullParser::commonInit ()
89 entityMap[
"apos"] =
"'";
90 entityMap[
"gt"] =
">";
91 entityMap[
"lt"] =
"<";
92 entityMap[
"quot"] =
"\"";
93 entityMap[
"amp"] =
"&";
94 for (
int i = 0; i < nspSize; i++)
108XmlPullParser::state (
int eventType)
113 return "START_DOCUMENT";
115 return "END_DOCUMENT";
127 return "IGNORABLE_WHITESPACE";
129 return "PROCESSING_INSTRUCTION";
135 return "Illegal state";
142bool 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);
153bool 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);
266XmlPullParser::exception (std::string desc)
277XmlPullParser::nextImpl ()
302 parseStartTag (
false);
310 pushText (
'<', !token);
323 type = parseLegacy (token);
324 if (type != XML_DECL)
332XmlPullParser::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 !=
'?')
471XmlPullParser::parseDoctype (
bool bpush)
485 exception (unexpected_eof);
497 if ((--nesting) == 0)
510XmlPullParser::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];
536XmlPullParser::peekType ()
563std::string XmlPullParser::get (
int pos)
567 return tmp.substr (pos, txtPos - pos);
572XmlPullParser::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;
590XmlPullParser::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;
710XmlPullParser::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));
767XmlPullParser::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)
798XmlPullParser::read (char c)
801 std::string sa (1, (char) a), sc (1, c);
803 exception ("expected: '" + sc + "' actual: '" + sa + "'");
808XmlPullParser::read ()
812 result = peekbuf (0);
834XmlPullParser::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;
883std::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);
909XmlPullParser::skip ()
915 if (c >
' ' || c == -1)
928 else if (isProp (feature,
false,
"relaxed"))
945 if (entityMap.empty ())
946 exception (
"entity replacement text must be defined after setInput!");
947 entityMap[entity] = value;
955 exception (
"IndexOutOfBoundsException");;
962 return nspStack[pos << 1];
968 return nspStack[(pos << 1) + 1];
975 return "http://www.w3.org/XML/1998/namespace";
976 if (
"xmlns" == prefx)
977 return "http://www.w3.org/2000/xmlns/";
986 if (nspStack[i].empty ())
987 return nspStack[i + 1];
990 else if (prefx == nspStack[i])
991 return nspStack[i + 1];
1007 std::ostringstream buf (std::ios::ate);
1009 buf << (type < 11 ? state (type) :
"Unknown Event");
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] <<
"'";
1037 else if (type !=
TEXT)
1041 buf <<
"(whitespace)";
1048 if (txt.length () > 16)
1049 txt = txt.substr (0, 16) +
"...";
1052 buf <<
" @" << line <<
":" << column;
1060 exception (illegal_type);
1067 return type <
TEXT || (type ==
ENTITY_REF && unresolved) ?
"" : get (0);
1081 poslen[1] = name.length ();
1082 return name.c_str ();
1097 exception (illegal_type);
1104 if (index >= attributeCount)
1105 exception (
"IndexOutOfBoundsException()");
1106 return attributes[index << 2];
1112 if (index >= attributeCount)
1113 exception (
"IndexOutOfBoundsException()");
1114 return attributes[(index << 2) + 2];
1120 if (index >= attributeCount)
1121 exception (
"IndexOutOfBoundsException()");
1122 return attributes[(index << 2) + 1];
1128 if (index >= attributeCount)
1129 exception (
"IndexOutOfBoundsException()");
1130 return attributes[(index << 2) + 3];
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];
1164 || (minType >=
TEXT && peekType () >=
TEXT));
1194 skipNextTag =
false;
1198 if (type ==
TEXT && isWspace)
1201 exception (
"unexpected type");
1210 || (!nam.empty () && nam !=
getName ()))
1211 exception (
"expected: " + state (
Type) +
" {" + ns +
"}" + nam);
1218 exception (
"precondition: START_TAG");
1232 exception (
"END_TAG expected");
1243 else if (isProp (feature,
false,
"relaxed"))
1247 exception (
"unsupported feature: " + feature);
1275 int eventType =
next();
#define FEATURE_PROCESS_NAMESPACES
std::string getNamespace()
const char * getTextCharacters(int *poslen)
bool getFeature(std::string feature)
void require(int type, std::string ns, std::string name)
std::string getInputEncoding()
std::string getAttributeValue(int index)
std::string getPositionDescription()
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)