OW_XMLPullParser.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00036 #include "OW_config.h"
00037 #include "OW_XMLPullParser.hpp"
00038 #include "OW_Format.hpp"
00039 #include "OW_Assertion.hpp"
00040 #include "OW_XMLUnescape.hpp"
00041 #include "OW_XMLParseException.hpp"
00042 #include <algorithm> // for std::lower_bound
00043 
00044 namespace OW_NAMESPACE
00045 {
00046 
00048 XMLPullParser::~XMLPullParser()
00049 {
00050 }
00051 
00053 void
00054 XMLPullParser::prime()
00055 {
00056    if (!(m_good = m_parser.next(m_curTok)))
00057    {
00058       OW_THROWXML(XMLParseException::SEMANTIC_ERROR, "Empty XML");
00059    }
00060    if (m_curTok.type == XMLToken::XML_DECLARATION)
00061    {
00062       if (!(m_good = m_parser.next(m_curTok)))
00063       {
00064          OW_THROWXML(XMLParseException::SEMANTIC_ERROR, "Empty XML");
00065       }
00066       skipData();
00067    }
00068    if (m_curTok.type == XMLToken::DOCTYPE)
00069    {
00070       if (!(m_good = m_parser.next(m_curTok)))
00071       {
00072          OW_THROWXML(XMLParseException::SEMANTIC_ERROR, "Empty XML");
00073       }
00074       skipData();
00075    }
00076 }
00078 XMLPullParser::XMLPullParser(const String& str)
00079    : m_ptfs(new TempFileStream())
00080    , m_parser()
00081    , m_curTok()
00082    , m_good(true)
00083 {
00084    *m_ptfs << str;
00085    m_parser.setInput(*m_ptfs);
00086    prime();
00087 }
00089 XMLPullParser::XMLPullParser(std::istream& istr)
00090    : m_ptfs()
00091    , m_parser(istr)
00092    , m_curTok()
00093    , m_good(true)
00094 {
00095    prime();
00096 }
00098 XMLPullParser::XMLPullParser()
00099    : m_good(false)
00100 {
00101 }
00102 
00104 String
00105 XMLPullParser::getAttribute(const char* const attrId, bool throwIfError) const
00106 {
00107    OW_ASSERT(m_curTok.type == XMLToken::START_TAG);
00108    for (unsigned i = 0; i < m_curTok.attributeCount; i++)
00109    {
00110       const XMLToken::Attribute& attr = m_curTok.attributes[i];
00111       // Should this be case insensentive? NO
00112       if (attr.name.equals(attrId))
00113       {
00114          return XMLUnescape(attr.value.c_str(), attr.value.length());
00115       }
00116    }
00117    if (throwIfError)
00118    {
00119       OW_THROWXML(XMLParseException::BAD_ATTRIBUTE_NAME,
00120                Format("Failed to find "
00121                   "attribute: %1 in node: %2", attrId, m_curTok.text).c_str() );
00122    }
00123    return String();
00124 }
00126 void
00127 XMLPullParser::mustGetChild()
00128 {
00129    if (!m_good)
00130    {
00131       m_good = false;
00132       OW_THROWXML(XMLParseException::SEMANTIC_ERROR,
00133          Format("XMLPullParser::mustGetChild() failed.  parser = %1",
00134             *this).c_str());
00135    }
00136    getChild();
00137    if (!m_good)
00138    {
00139       m_good = false;
00140       OW_THROWXML(XMLParseException::SEMANTIC_ERROR,
00141          Format("XMLPullParser::mustGetChild() failed.  parser = %1",
00142             *this).c_str());
00143    }
00144 }
00146 void
00147 XMLPullParser::getChild()
00148 {
00149    if (!m_good)
00150    {
00151       return;
00152    }
00153    for (;;)
00154    {
00155       nextToken();
00156       if (!m_good)
00157       {
00158          return;
00159       }
00160       switch (m_curTok.type)
00161       {
00162          case XMLToken::END_TAG: // hit the end, no children
00163             m_good = false;
00164          case XMLToken::START_TAG: // valid token for a child
00165             return;
00166          default:
00167             break;
00168       }
00169    }
00170 }
00172 void
00173 XMLPullParser::getNextTag(bool throwIfError)
00174 {
00175    nextToken();
00176    skipData();
00177    if (!m_good && throwIfError)
00178    {
00179       OW_THROWXML(XMLParseException::SEMANTIC_ERROR,
00180          Format("XMLPullParser::getNext() failed.  parser = %1",
00181             *this).c_str());
00182    }
00183 }
00185 void
00186 XMLPullParser::getNext(bool throwIfError)
00187 {
00188    nextToken();
00189    if (!m_good && throwIfError)
00190    {
00191       OW_THROWXML(XMLParseException::SEMANTIC_ERROR,
00192          Format("XMLPullParser::getNext() failed.  parser = %1",
00193             *this).c_str());
00194    }
00195 }
00197 void
00198 XMLPullParser::mustGetEndTag()
00199 {
00200    skipData();
00201    if (m_curTok.type != XMLToken::END_TAG)
00202    {
00203       OW_THROWXML(XMLParseException::SEMANTIC_ERROR,
00204          Format("XMLPullParser::mustGetEndTag() failed.  parser = %1",
00205             *this).c_str());
00206    }
00207    getNext();
00208    skipData();
00209 }
00211 String
00212 XMLPullParser::getName() const
00213 {
00214    OW_ASSERT(m_curTok.type == XMLToken::START_TAG || m_curTok.type == XMLToken::END_TAG);
00215    return XMLUnescape(m_curTok.text.c_str(), m_curTok.text.length());
00216 }
00218 String
00219 XMLPullParser::getData() const
00220 {
00221    OW_ASSERT(m_curTok.type == XMLToken::CONTENT || m_curTok.type == XMLToken::CDATA);
00222    return XMLUnescape(m_curTok.text.c_str(), m_curTok.text.length());
00223 }
00225 bool
00226 XMLPullParser::isData() const
00227 {
00228    return m_curTok.type == XMLToken::CONTENT || m_curTok.type == XMLToken::CDATA;
00229 }
00231 void
00232 XMLPullParser::nextToken()
00233 {
00234    do
00235    {
00236       m_good = m_parser.next(m_curTok);
00237    } while (m_curTok.type == XMLToken::COMMENT && m_good);
00238 }
00240 void
00241 XMLPullParser::skipData()
00242 {
00243    while (isData() && m_good)
00244    {
00245       nextToken();
00246    }
00247 }
00249 std::ostream& operator<<(std::ostream& ostr, const XMLPullParser& p)
00250 {
00251    ostr << "m_good = " << p.m_good << '\n';
00252    switch (p.m_curTok.type)
00253    {
00254       case XMLToken::INVALID:
00255          ostr << "*INVALID*\n";
00256          break;
00257       case XMLToken::XML_DECLARATION:
00258          ostr << "<xml>\n";
00259          break;
00260       case XMLToken::START_TAG:
00261          ostr << '<' << p.m_curTok.text << ' ';
00262          for (unsigned int x = 0; x < p.m_curTok.attributeCount; ++x)
00263          {
00264             ostr << p.m_curTok.attributes[x].name << "=\"" <<
00265                p.m_curTok.attributes[x].value << "\" ";
00266          }
00267          ostr << ">\n";
00268          break;
00269       case XMLToken::END_TAG:
00270          ostr << "</" << p.m_curTok.text << ">\n";
00271          break;
00272       case XMLToken::COMMENT:
00273          ostr << "<--" << p.m_curTok.text << "-->\n";
00274          break;
00275       case XMLToken::CDATA:
00276          ostr << "<CDATA[[" << p.m_curTok.text << "]]>\n";
00277          break;
00278       case XMLToken::DOCTYPE:
00279          ostr << "<DOCTYPE>\n";
00280          break;
00281       case XMLToken::CONTENT:
00282          ostr << "CONTENT: " << p.m_curTok.text << '\n';
00283          break;
00284       default:
00285          ostr << "Unknown token type\n";
00286    }
00287    return ostr;
00288 }
00289 
00290 } // end namespace OW_NAMESPACE
00291 

Generated on Thu Feb 9 08:48:20 2006 for openwbem by  doxygen 1.4.6