wsdlpull 1.23
|
00001 /* Copyright (c) 2005,2007 Vivek Krishna 00002 * Based on kxml2 by Stefan Haustein, Oberhausen, Rhld., Germany 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy 00004 * of this software and associated documentation files (the "Software"), to deal 00005 * in the Software without restriction, including without limitation the rights 00006 * to use, copy, modify, merge, publish, distribute, sublicense, and/or 00007 * sell copies of the Software, and to permit persons to whom the Software is 00008 * furnished to do so, subject to the following conditions: 00009 * 00010 * The above copyright notice and this permission notice shall be included in 00011 * all copies or substantial portions of the Software. 00012 * 00013 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00014 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00015 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00016 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00017 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00018 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 00019 * IN THE SOFTWARE. */ 00020 00021 #include "xmlpull/XmlPullParser.h" 00022 #include "xmlpull/XmlPullParserException.h" 00023 #include "xmlpull/XmlUtils.h" 00024 // 00025 #include <cstring> 00026 00027 00028 XmlPullParser::XmlPullParser (std::istream & is) 00029 :unexpected_eof ("Unexpected EOF"), 00030 illegal_type ("wrong Event Type"), 00031 nspStack (16), 00032 elementStack (16), 00033 attributes (16), 00034 reader (is) 00035 { 00036 initBuf (); 00037 commonInit (); 00038 } 00039 00040 00041 XmlPullParser::XmlPullParser (void) 00042 :unexpected_eof ("Unexpected EOF"), 00043 illegal_type ("wrong Event Type"), 00044 nspStack (16), 00045 elementStack (16), 00046 attributes (16), 00047 reader (std::cin) 00048 { 00049 initBuf (); 00050 commonInit (); 00051 } 00052 00053 00054 void 00055 XmlPullParser::initBuf () 00056 { 00057 srcBuf = new char[8192]; 00058 srcBuflength = 8192; 00059 txtBuf = new char[256]; 00060 txtBufSize = 256; 00061 nspCounts = new int[8]; 00062 nspSize = 8; 00063 } 00064 00065 00066 //does common initializations 00067 void 00068 XmlPullParser::commonInit () 00069 { 00070 line = 1; 00071 column = 0; 00072 type = START_DOCUMENT; 00073 name = ""; 00074 Ns = ""; 00075 degenerated = false; 00076 attributeCount = -1; 00077 encoding = ""; 00078 version = ""; 00079 standalone = false; 00080 unresolved = false; 00081 LEGACY = 999; 00082 XML_DECL = 998; 00083 srcPos = 0; 00084 srcCount = 0; 00085 peekCount = 0; 00086 depth = 0; 00087 relaxed = false; 00088 skipNextTag=false; 00089 entityMap["apos"] = "'"; 00090 entityMap["gt"] = ">"; 00091 entityMap["lt"] = "<"; 00092 entityMap["quot"] = "\""; 00093 entityMap["amp"] = "&"; 00094 for (int i = 0; i < nspSize; i++) 00095 nspCounts[i] = 0; 00096 } 00097 00098 00099 XmlPullParser::~XmlPullParser (void) 00100 { 00101 delete [] srcBuf; 00102 delete [] txtBuf; 00103 delete [] nspCounts; 00104 } 00105 00106 00107 std::string 00108 XmlPullParser::state (int eventType) 00109 { 00110 switch (eventType) 00111 { 00112 case 0: 00113 return "START_DOCUMENT"; 00114 case 1: 00115 return "END_DOCUMENT"; 00116 case 2: 00117 return "START_TAG"; 00118 case 3: 00119 return "END_TAG"; 00120 case 4: 00121 return "TEXT"; 00122 case 5: 00123 return "CDSECT"; 00124 case 6: 00125 return "ENTITY_REF"; 00126 case 7: 00127 return "IGNORABLE_WHITESPACE"; 00128 case 8: 00129 return "PROCESSING_INSTRUCTION"; 00130 case 9: 00131 return "COMMENT"; 00132 case 10: 00133 return "DOCDECL"; 00134 default: 00135 return "Illegal state"; 00136 break; 00137 } 00138 return ""; 00139 } 00140 00141 00142 bool XmlPullParser::isProp (std::string n1, bool prop, std::string n2) 00143 { 00144 if (n1.find ("http://xmlpull.org/v1/doc/") != 0) 00145 return false; 00146 if (prop) 00147 return (n1.substr (42) == n2); 00148 else 00149 return (n1.substr (40) == n2); 00150 } 00151 00152 00153 bool XmlPullParser::adjustNsp () 00154 { 00155 bool 00156 any = false; 00157 for (int i = 0; i < attributeCount << 2; i += 4) 00158 00159 { 00160 std::string 00161 attrName = attributes[i + 2]; 00162 int 00163 cut = attrName.find (":"); 00164 std::string 00165 prefx; 00166 // Creating a variable named 'prefix' generates a warning about hiding the member, so I changed it to 'prefx'. -KEC 00167 if (cut != -1) 00168 00169 { 00170 prefx = attrName.substr (0, cut); 00171 attrName = attrName.substr (cut + 1); 00172 } 00173 00174 else if (attrName == "xmlns") 00175 00176 { 00177 prefx = attrName; 00178 attrName = ""; 00179 } 00180 00181 else 00182 continue; 00183 if (prefx != "xmlns") 00184 { 00185 any = true; 00186 } 00187 else 00188 { 00189 unsigned int j = (nspCounts[depth]++) << 1; 00190 00191 //nspStack = ensureCapacity(nspStack, j + 2); 00192 if (nspStack.size () <= j + 2) 00193 nspStack.resize (j + 2 + RESIZE_BUFFER); 00194 nspStack[j] = attrName; 00195 nspStack[j + 1] = attributes[i + 3]; 00196 if (!attrName.empty () && attributes[i + 3] == "") 00197 exception ("illegal empty namespace"); 00198 00199 //vivek,array copy?? 00200 int to = ((--attributeCount) << 2) - i; 00201 for (int p = 1; p <= to; p++) 00202 attributes[i + p - 1] = attributes[i + 4 + p - 1]; 00203 i -= 4; 00204 } 00205 } 00206 if (any) 00207 00208 { 00209 for (int i = (attributeCount << 2) - 4; i >= 0; i -= 4) 00210 00211 { 00212 std::string 00213 attrName = attributes[i + 2]; 00214 int 00215 cut = attrName.find (":"); 00216 if (cut == 0 && !relaxed) 00217 exception ("illegal attribute name: " + attrName); 00218 00219 else if (cut != -1) 00220 00221 { 00222 std::string 00223 attrPrefix = attrName.substr (0, cut); 00224 attrName = attrName.substr (cut + 1); 00225 std::string 00226 attrNs = getNamespace (attrPrefix); 00227 if (attrNs.empty () && !relaxed) 00228 exception ("Undefined Prefix: " + attrPrefix + " in "); 00229 attributes[i] = attrNs; 00230 attributes[i + 1] = attrPrefix; 00231 attributes[i + 2] = attrName; 00232 if (!relaxed) 00233 00234 { 00235 for (int j = (attributeCount << 2) - 4; j > i; j -= 4) 00236 if (attrName == attributes[j + 2] 00237 && attrNs == attributes[j]) 00238 exception ("Duplicate Attribute: {" 00239 + attrNs + "}" + attrName); 00240 } 00241 } 00242 } 00243 } 00244 int cut = name.find (":"); 00245 if (cut == 0 && !relaxed) 00246 exception ("illegal tag name: " + name); 00247 00248 else if (cut != -1) 00249 { 00250 prefix = name.substr (0, cut); 00251 name = name.substr (cut + 1); 00252 } 00253 Ns = getNamespace (prefix); 00254 if (Ns.empty ()) 00255 00256 { 00257 if (!prefix.empty () && !relaxed) 00258 exception ("undefined prefix: " + prefix); 00259 Ns = NO_NAMESPACE; 00260 } 00261 return any; 00262 } 00263 00264 00265 void 00266 XmlPullParser::exception (std::string desc) 00267 { 00268 XmlPullParserException e (desc, state (type), line, column); 00269 throw e; 00270 } 00271 00272 00276 void 00277 XmlPullParser::nextImpl () 00278 { 00279 if (type == END_TAG) 00280 depth--; 00281 while (true) 00282 { 00283 attributeCount = -1; 00284 if (degenerated) 00285 00286 { 00287 degenerated = false; 00288 type = END_TAG; 00289 return; 00290 } 00291 prefix = ""; 00292 name = ""; 00293 Ns = ""; 00294 text = ""; 00295 type = peekType (); 00296 switch (type) 00297 { 00298 case ENTITY_REF: 00299 pushEntity (); 00300 return; 00301 case START_TAG: 00302 parseStartTag (false); 00303 return; 00304 case END_TAG: 00305 parseEndTag (); 00306 return; 00307 case END_DOCUMENT: 00308 return; 00309 case TEXT: 00310 pushText ('<', !token); 00311 if (depth == 0) 00312 00313 { 00314 if (isWspace) 00315 type = IGNORABLE_WHITESPACE; 00316 00317 // make exception switchable for instances.chg... !!!! 00318 // else 00319 // exception ("text '"+getText ()+"' not allowed outside root element"); 00320 } 00321 return; 00322 default: 00323 type = parseLegacy (token); 00324 if (type != XML_DECL) 00325 return; 00326 } 00327 } 00328 } 00329 00330 00331 int 00332 XmlPullParser::parseLegacy (bool bpush) 00333 { 00334 std::string req = ""; 00335 int term; 00336 int result; 00337 int prev = 0; 00338 read (); // < 00339 int c = read (); 00340 if (c == '?') 00341 00342 { 00343 if ((peekbuf (0) == 'x' || peekbuf (0) == 'X') 00344 && (peekbuf (1) == 'm' || peekbuf (1) == 'M')) 00345 00346 { 00347 if (bpush) 00348 00349 { 00350 push (peekbuf (0)); 00351 push (peekbuf (1)); 00352 } 00353 read (); 00354 read (); 00355 if ((peekbuf (0) == 'l' || peekbuf (0) == 'L') 00356 && peekbuf (1) <= ' ') 00357 00358 { 00359 if (line != 1 || column > 4) 00360 exception ("PI must not start with xml"); 00361 parseStartTag (true); 00362 if (attributeCount < 1 || "version" != attributes[2]) 00363 exception ("version expected"); 00364 version = attributes[3]; 00365 int pos = 1; 00366 if (pos < attributeCount && "encoding" == attributes[2 + 4]) 00367 00368 { 00369 encoding = attributes[3 + 4]; 00370 pos++; 00371 } 00372 if (pos < attributeCount 00373 && "standalone" == attributes[4 * pos + 2]) 00374 00375 { 00376 std::string st = attributes[3 + 4 * pos]; 00377 if ("yes" == st) 00378 standalone = true; 00379 00380 else if ("no" == st) 00381 standalone = false; 00382 00383 else 00384 exception ("illegal standalone value: " + st); 00385 pos++; 00386 } 00387 if (pos != attributeCount) 00388 exception ("illegal xmldecl"); 00389 isWspace = true; 00390 txtPos = 0; 00391 return XML_DECL; 00392 } 00393 } 00394 00395 /* int c0 = read (); 00396 int c1 = read (); 00397 int */ 00398 term = '?'; 00399 result = PROCESSING_INSTRUCTION; 00400 } 00401 00402 else if (c == '!') 00403 00404 { 00405 if (peekbuf (0) == '-') 00406 00407 { 00408 result = COMMENT; 00409 req = "--"; 00410 term = '-'; 00411 } 00412 00413 else if (peekbuf (0) == '[') 00414 00415 { 00416 result = CDSECT; 00417 req = "[CDATA["; 00418 term = ']'; 00419 bpush = true; 00420 } 00421 00422 else 00423 00424 { 00425 result = DOCDECL; 00426 req = "DOCTYPE"; 00427 term = -1; 00428 } 00429 } 00430 00431 else 00432 00433 { 00434 exception ("illegal: <" + c); 00435 return -1; 00436 } 00437 for (unsigned int i = 0; i < req.length (); i++) 00438 read (req.at (i)); 00439 if (result == DOCDECL) 00440 parseDoctype (bpush); 00441 00442 else 00443 00444 { 00445 while (true) 00446 00447 { 00448 c = read (); 00449 if (c == -1) 00450 exception (unexpected_eof); 00451 if (bpush) 00452 push (c); 00453 if ((term == '?' || c == term) 00454 && peekbuf (0) == term && peekbuf (1) == '>') 00455 break; 00456 prev = c; 00457 } 00458 if (term == '-' && prev == '-' && !relaxed) 00459 exception ("illegal comment delimiter: --->"); 00460 read (); 00461 read (); 00462 if (bpush && term != '?') 00463 txtPos--; 00464 } 00465 return result; 00466 } 00467 00468 00470 void 00471 XmlPullParser::parseDoctype (bool bpush) 00472 { 00473 int nesting = 1; 00474 bool quoted = false; 00475 00476 // read(); 00477 while (true) 00478 00479 { 00480 int i = read (); 00481 switch (i) 00482 00483 { 00484 case -1: 00485 exception (unexpected_eof); 00486 case '\'': 00487 quoted = !quoted; 00488 break; 00489 case '<': 00490 if (!quoted) 00491 nesting++; 00492 break; 00493 case '>': 00494 if (!quoted) 00495 00496 { 00497 if ((--nesting) == 0) 00498 return; 00499 } 00500 break; 00501 } 00502 if (bpush) 00503 push (i); 00504 } 00505 } 00506 00507 00508 /* precondition: </ consumed */ 00509 void 00510 XmlPullParser::parseEndTag () 00511 { 00512 read (); // '<' 00513 read (); // '/' 00514 name = readName (); 00515 skip (); 00516 read ('>'); 00517 int sp = (depth - 1) << 2; 00518 if (!relaxed) 00519 00520 { 00521 if (depth == 0) 00522 exception ("element stack empty"); 00523 if (name != elementStack[sp + 3]) 00524 exception ("expected: " + elementStack[sp + 3]); 00525 } 00526 00527 else if (depth == 0 || name != elementStack[sp + 3]) 00528 return; 00529 Ns = elementStack[sp]; 00530 prefix = elementStack[sp + 1]; 00531 name = elementStack[sp + 2]; 00532 } 00533 00534 00535 int 00536 XmlPullParser::peekType () 00537 { 00538 switch (peekbuf (0)) 00539 00540 { 00541 case -1: 00542 return END_DOCUMENT; 00543 case '&': 00544 return ENTITY_REF; 00545 case '<': 00546 switch (peekbuf (1)) 00547 00548 { 00549 case '/': 00550 return END_TAG; 00551 case '?': 00552 case '!': 00553 return LEGACY; 00554 default: 00555 return START_TAG; 00556 } 00557 default: 00558 return TEXT; 00559 } 00560 } 00561 00562 00563 std::string XmlPullParser::get (int pos) 00564 { 00565 std::string 00566 tmp (txtBuf); 00567 return tmp.substr (pos, txtPos - pos); 00568 } 00569 00570 00571 void 00572 XmlPullParser::push (int c) 00573 { 00574 isWspace &= c <= ' '; 00575 if (txtPos >= txtBufSize - 1) 00576 00577 { 00578 char *bigger = new char[txtBufSize = txtPos * 4 / 3 + 4]; 00579 memcpy (bigger, txtBuf, txtPos); 00580 delete[] txtBuf; 00581 txtBuf = bigger; 00582 } 00583 txtBuf[txtPos++] = (char) c; 00584 txtBuf[txtPos] = 0; 00585 } 00586 00587 00589 void 00590 XmlPullParser::parseStartTag (bool xmldecl) 00591 { 00592 if (!xmldecl) 00593 read (); 00594 name = readName (); 00595 attributeCount = 0; 00596 while (true) 00597 00598 { 00599 skip (); 00600 int c = peekbuf (0); 00601 if (xmldecl) 00602 00603 { 00604 if (c == '?') 00605 00606 { 00607 read (); 00608 read ('>'); 00609 return; 00610 } 00611 } 00612 00613 else 00614 00615 { 00616 if (c == '/') 00617 00618 { 00619 degenerated = true; 00620 read (); 00621 skip (); 00622 read ('>'); 00623 break; 00624 } 00625 if (c == '>' && !xmldecl) 00626 00627 { 00628 read (); 00629 break; 00630 } 00631 } 00632 if (c == -1) 00633 exception (unexpected_eof); 00634 std::string attrName = readName (); 00635 if (attrName.empty ()) 00636 exception ("attr name expected"); 00637 skip (); 00638 read ('='); 00639 skip (); 00640 int delimiter = read (); 00641 if (delimiter != '\'' && delimiter != '"') 00642 00643 { 00644 if (!relaxed) 00645 exception ("<" 00646 + name + ">: invalid delimiter: " + (char) delimiter); 00647 delimiter = ' '; 00648 } 00649 unsigned int i = (attributeCount++) << 2; 00650 00651 //attributes = ensureCapacity(attributes, i + 4); 00652 if (attributes.size () <= i + 4) 00653 attributes.resize (i + 4 + RESIZE_BUFFER); 00654 attributes[i++] = ""; 00655 attributes[i++] = ""; 00656 attributes[i++] = attrName; 00657 int p = txtPos; 00658 pushText (delimiter, true); 00659 attributes[i] = get (p); 00660 txtPos = p; 00661 if (delimiter != ' ') 00662 read (); // skip endquote 00663 } 00664 unsigned int sp = depth++ << 2; 00665 00666 //elementStack = ensureCapacity(elementStack, sp + 4,elementStackSize); 00667 if (elementStack.size () <= sp + 4) 00668 elementStack.resize (sp + 4 + RESIZE_BUFFER); 00669 elementStack[sp + 3] = name; 00670 00671 /* vivek ,avoided the increment array logic..fix later*/ 00672 if (depth >= nspSize) 00673 00674 { 00675 int *bigger = new int[nspSize + 4]; 00676 int i = 0; 00677 for (i = 0; i < nspSize; i++) 00678 bigger[i] = nspCounts[i]; 00679 for (i = nspSize; i < nspSize + 4; i++) 00680 bigger[i] = 0; 00681 delete [] nspCounts; 00682 nspCounts = bigger; 00683 nspSize += 4; 00684 } 00685 nspCounts[depth] = nspCounts[depth - 1]; 00686 for (int i = attributeCount - 1; i > 0; i--) 00687 00688 { 00689 for (int j = 0; j < i; j++) 00690 00691 { 00692 if (getAttributeName (i) == getAttributeName (j)) 00693 exception ("Duplicate Attribute: " + getAttributeName (i)); 00694 } 00695 } 00696 if (processNsp) 00697 adjustNsp (); 00698 00699 else 00700 Ns = ""; 00701 elementStack[sp] = Ns; 00702 elementStack[sp + 1] = prefix; 00703 elementStack[sp + 2] = name; 00704 } 00705 00706 00709 void 00710 XmlPullParser::pushEntity () 00711 { 00712 read (); // & 00713 int pos = txtPos; 00714 while (true) 00715 00716 { 00717 int c = read (); 00718 if (c == ';') 00719 break; 00720 if (relaxed && (c == '<' || c == '&' || c <= ' ')) 00721 00722 { 00723 if (c != -1) 00724 push (c); 00725 return; 00726 } 00727 if (c == -1) 00728 exception (unexpected_eof); 00729 push (c); 00730 } 00731 std::string code = get (pos); 00732 txtPos = pos; 00733 if (token && type == ENTITY_REF) 00734 name = code; 00735 if (code[0] == '#') 00736 00737 { 00738 int c = (code[1] == 'x' ? XmlUtils::parseInt (code.substr (2),16) 00739 : XmlUtils::parseInt (code.substr (1))); 00740 push (c); 00741 return; 00742 } 00743 std::string result = (std::string) entityMap[code]; 00744 unresolved = result == ""; 00745 if (unresolved) 00746 00747 { 00748 if (!token) 00749 exception ("unresolved: &" + code + ";"); 00750 } 00751 00752 else 00753 00754 { 00755 for (unsigned int i = 0; i < result.length (); i++) 00756 push (result.at (i)); 00757 } 00758 } 00759 00760 00766 void 00767 XmlPullParser::pushText (int delimiter, bool resolveEntities) 00768 { 00769 int next = peekbuf (0); 00770 while (next != -1 && next != delimiter) // covers eof, '<', '"' 00771 { 00772 if (delimiter == ' ') 00773 if (next <= ' ' || next == '>') 00774 break; 00775 if (next == '&') 00776 00777 { 00778 if (!resolveEntities) 00779 break; 00780 pushEntity (); 00781 } 00782 00783 else if (next == '\n' && type == START_TAG) 00784 00785 { 00786 read (); 00787 push (' '); 00788 } 00789 00790 else 00791 push (read ()); 00792 next = peekbuf (0); 00793 } 00794 } 00795 00796 00797 void 00798 XmlPullParser::read (char c) 00799 { 00800 int a = read (); 00801 std::string sa (1, (char) a), sc (1, c); 00802 if (a != c) 00803 exception ("expected: '" + sc + "' actual: '" + sa + "'"); 00804 } 00805 00806 00807 int 00808 XmlPullParser::read () 00809 { 00810 int result; 00811 if (peekCount == 0) 00812 result = peekbuf (0); 00813 00814 else 00815 00816 { 00817 result = peek[0]; 00818 peek[0] = peek[1]; 00819 } 00820 peekCount--; 00821 column++; 00822 if (result == '\n') 00823 00824 { 00825 line++; 00826 column = 1; 00827 } 00828 return result; 00829 } 00830 00831 00833 int 00834 XmlPullParser::peekbuf (int pos) 00835 { 00836 while (pos >= peekCount) 00837 00838 { 00839 int nw; 00840 if (srcBuflength <= 1) 00841 nw = reader.get (); 00842 00843 else if (srcPos < srcCount) 00844 nw = srcBuf[srcPos++]; 00845 00846 else 00847 00848 { 00849 srcCount = reader.read (srcBuf, srcBuflength).gcount (); 00850 if (srcCount <= 0) 00851 nw = -1; 00852 00853 else 00854 nw = srcBuf[0]; 00855 srcPos = 1; 00856 } 00857 if (nw == '\r') 00858 00859 { 00860 wasCR = true; 00861 peek[peekCount++] = '\n'; 00862 } 00863 00864 else 00865 00866 { 00867 if (nw == '\n') 00868 00869 { 00870 if (!wasCR) 00871 peek[peekCount++] = '\n'; 00872 } 00873 00874 else 00875 peek[peekCount++] = nw; 00876 wasCR = false; 00877 } 00878 } 00879 return peek[pos]; 00880 } 00881 00882 00883 std::string XmlPullParser::readName () 00884 { 00885 int pos = txtPos; 00886 int c = peekbuf (0); 00887 if ((c < 'a' || c > 'z') 00888 && (c < 'A' || c > 'Z') && c != '_' && c != ':' && c < 0x0c0) 00889 exception ("name expected"); 00890 00891 do 00892 00893 { 00894 push (read ()); 00895 c = peekbuf (0); 00896 } 00897 while ((c >= 'a' && c <= 'z') 00898 || (c >= 'A' && c <= 'Z') 00899 || (c >= '0' && c <= '9') 00900 || c == '_' || c == '-' || c == ':' || c == '.' || c >= 0x0b7); 00901 std::string 00902 result = get (pos); 00903 txtPos = pos; 00904 return result; 00905 } 00906 00907 00908 void 00909 XmlPullParser::skip () 00910 { 00911 while (true) 00912 00913 { 00914 int c = peekbuf (0); 00915 if (c > ' ' || c == -1) 00916 break; 00917 read (); 00918 } 00919 } 00920 00921 00922 //--------------- public part starts here... --------------- 00923 bool XmlPullParser::getFeature (std::string feature) 00924 { 00925 if (FEATURE_PROCESS_NAMESPACES == feature) 00926 return processNsp; 00927 00928 else if (isProp (feature, false, "relaxed")) 00929 return relaxed; 00930 00931 else 00932 return false; 00933 } 00934 00935 00936 std::string XmlPullParser::getInputEncoding () 00937 { 00938 return encoding; 00939 } 00940 00941 00942 void 00943 XmlPullParser::defineEntityReplacementText (std::string entity, std::string value) 00944 { 00945 if (entityMap.empty ()) 00946 exception ("entity replacement text must be defined after setInput!"); 00947 entityMap[entity] = value; 00948 } 00949 00950 00951 int 00952 XmlPullParser::getNamespaceCount (int d) 00953 { 00954 if (d > depth) 00955 exception ("IndexOutOfBoundsException");; 00956 return nspCounts[d]; 00957 } 00958 00959 00960 std::string XmlPullParser::getNamespacePrefix (int pos) 00961 { 00962 return nspStack[pos << 1]; 00963 } 00964 00965 00966 std::string XmlPullParser::getNamespaceUri (int pos) 00967 { 00968 return nspStack[(pos << 1) + 1]; 00969 } 00970 00971 00972 std::string XmlPullParser::getNamespace (std::string prefx) 00973 { 00974 if ("xml" == prefx) 00975 return "http://www.w3.org/XML/1998/namespace"; 00976 if ("xmlns" == prefx) 00977 return "http://www.w3.org/2000/xmlns/"; 00978 for (int i = (getNamespaceCount (depth) << 1) - 2; i >= 0; i -= 2) 00979 00980 { 00981 if (prefx.empty ()) 00982 00983 { 00984 00985 //cout<<nspStack[i]<<nspStack[i+1]<<endl; 00986 if (nspStack[i].empty ()) 00987 return nspStack[i + 1]; 00988 } 00989 00990 else if (prefx == nspStack[i]) 00991 return nspStack[i + 1]; 00992 } 00993 return ""; 00994 } 00995 00996 00997 int 00998 XmlPullParser::getDepth () 00999 { 01000 return depth; 01001 } 01002 01003 01004 std::string 01005 XmlPullParser::getPositionDescription () 01006 { 01007 std::ostringstream buf (std::ios::ate); 01008 //vivek,replace 11 by the number of event types 01009 buf << (type < 11 ? state (type) : "Unknown Event"); 01010 buf << " "; 01011 if (type == START_TAG || type == END_TAG) 01012 01013 { 01014 if (degenerated) 01015 buf << "(empty) "; 01016 buf << "<"; 01017 if (type == END_TAG) 01018 buf << "/"; 01019 if (!prefix.empty ()) 01020 buf << "{" << Ns << "}" << prefix << ":"; 01021 buf << name; 01022 int 01023 cnt = attributeCount << 2; 01024 for (int i = 0; i < cnt; i += 4) 01025 01026 { 01027 buf << " "; 01028 if (!attributes[i + 1].empty ()) 01029 buf << "{" << attributes[i] << "}" << attributes[i + 1] << ":"; 01030 buf << attributes[i + 2] << "='" << attributes[i + 3] << "'"; 01031 } 01032 buf << ">"; 01033 } 01034 01035 else if (type == IGNORABLE_WHITESPACE); 01036 01037 else if (type != TEXT) 01038 buf << getText (); 01039 01040 else if (isWspace) 01041 buf << "(whitespace)"; 01042 01043 else 01044 01045 { 01046 std::string 01047 txt = getText (); 01048 if (txt.length () > 16) 01049 txt = txt.substr (0, 16) + "..."; 01050 buf << txt; 01051 } 01052 buf << " @" << line << ":" << column; 01053 return buf.str (); //replace buf with an ostream 01054 } 01055 01056 01057 bool XmlPullParser::isWhitespace () 01058 { 01059 if (type != TEXT && type != IGNORABLE_WHITESPACE && type != CDSECT) 01060 exception (illegal_type); 01061 return isWspace; 01062 } 01063 01064 01065 std::string XmlPullParser::getText () 01066 { 01067 return type < TEXT || (type == ENTITY_REF && unresolved) ? "" : get (0); 01068 } 01069 01070 01071 const char * 01072 XmlPullParser::getTextCharacters (int *poslen) 01073 { 01074 if (type >= TEXT) 01075 01076 { 01077 if (type == ENTITY_REF) 01078 01079 { 01080 poslen[0] = 0; 01081 poslen[1] = name.length (); 01082 return name.c_str (); //return name.toCharArray(); 01083 } 01084 poslen[0] = 0; 01085 poslen[1] = txtPos; 01086 return txtBuf; 01087 } 01088 poslen[0] = -1; 01089 poslen[1] = -1; 01090 return 0; 01091 } 01092 01093 01094 bool XmlPullParser::isEmptyElementTag () 01095 { 01096 if (type != START_TAG) 01097 exception (illegal_type); 01098 return degenerated; 01099 } 01100 01101 01102 std::string XmlPullParser::getAttributeNamespace (int index) 01103 { 01104 if (index >= attributeCount) 01105 exception ("IndexOutOfBoundsException()"); 01106 return attributes[index << 2]; 01107 } 01108 01109 01110 std::string XmlPullParser::getAttributeName (int index) 01111 { 01112 if (index >= attributeCount) 01113 exception ("IndexOutOfBoundsException()"); 01114 return attributes[(index << 2) + 2]; 01115 } 01116 01117 01118 std::string XmlPullParser::getAttributePrefix (int index) 01119 { 01120 if (index >= attributeCount) 01121 exception ("IndexOutOfBoundsException()"); 01122 return attributes[(index << 2) + 1]; 01123 } 01124 01125 01126 std::string XmlPullParser::getAttributeValue (int index) 01127 { 01128 if (index >= attributeCount) 01129 exception ("IndexOutOfBoundsException()"); 01130 return attributes[(index << 2) + 3]; 01131 } 01132 01133 01134 std::string XmlPullParser::getAttributeValue (std::string ns, std::string nam) 01135 { 01136 for (int i = (attributeCount << 2) - 4; i >= 0; i -= 4) 01137 01138 { 01139 if (attributes[i + 2] == nam && (ns.empty () || attributes[i] == ns)) 01140 return attributes[i + 3]; 01141 } 01142 return ""; 01143 } 01144 01145 01146 int 01147 XmlPullParser::next () 01148 { 01149 txtPos = 0; 01150 isWspace = true; 01151 int minType = 9999; 01152 token = false; 01153 01154 do 01155 01156 { 01157 nextImpl (); 01158 if (type < minType) 01159 minType = type; 01160 01161 // if (curr <= TEXT) type = curr; 01162 } 01163 while (minType > CDSECT // ignorable 01164 || (minType >= TEXT && peekType () >= TEXT)); 01165 type = minType; 01166 if (type > TEXT) 01167 type = TEXT; 01168 return type; 01169 } 01170 01171 01172 int 01173 XmlPullParser::nextToken () 01174 { 01175 isWspace = true; 01176 txtPos = 0; 01177 token = true; 01178 nextImpl (); 01179 return type; 01180 } 01181 01182 void 01183 XmlPullParser::prevTag() 01184 { 01185 skipNextTag=true; 01186 } 01187 01188 //---------------------------------------------------------------------- 01189 // utility methods to make XML parsing easier ... 01190 int 01191 XmlPullParser::nextTag () 01192 { 01193 if(skipNextTag){ 01194 skipNextTag = false; 01195 return type; 01196 } 01197 next (); 01198 if (type == TEXT && isWspace) 01199 next (); 01200 if (type != END_TAG && type != START_TAG && type != END_DOCUMENT) 01201 exception ("unexpected type"); 01202 return type; 01203 } 01204 01205 01206 void 01207 XmlPullParser::require (int Type, std::string ns, std::string nam) 01208 { 01209 if (Type != type || (!ns.empty () && ns != getNamespace ()) 01210 || (!nam.empty () && nam != getName ())) 01211 exception ("expected: " + state (Type) + " {" + ns + "}" + nam); 01212 } 01213 01214 01215 std::string XmlPullParser::nextText () 01216 { 01217 if (type != START_TAG) 01218 exception ("precondition: START_TAG"); 01219 next (); 01220 std::string 01221 result; 01222 if (type == TEXT) 01223 01224 { 01225 result = getText (); 01226 next (); 01227 } 01228 01229 else 01230 result = ""; 01231 if (type != END_TAG) 01232 exception ("END_TAG expected"); 01233 return result; 01234 } 01235 01236 01237 void 01238 XmlPullParser::setFeature (std::string feature, bool value) 01239 { 01240 if (FEATURE_PROCESS_NAMESPACES == feature) 01241 processNsp = value; 01242 01243 else if (isProp (feature, false, "relaxed")) 01244 relaxed = value; 01245 01246 else 01247 exception ("unsupported feature: " + feature); 01248 } 01249 01250 /* 01251 void 01252 XmlPullParser::setProperty(std::string property, std::string value) 01253 { 01254 if(isProp(property, true, "location")) 01255 { 01256 location = value; 01257 } 01258 else 01259 exception ("unsupported property: " + property); 01260 } 01261 */ 01262 01268 // Implementation copied from Alek's mail... 01269 01270 void 01271 XmlPullParser::skipSubTree() { 01272 require(START_TAG, "", ""); 01273 int level = 1; 01274 while (level > 0) { 01275 int eventType = next(); 01276 if (eventType == END_TAG) { 01277 --level; 01278 } 01279 else if (eventType == START_TAG) { 01280 ++level; 01281 } 01282 } 01283 } 01284