⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlparser.cpp

📁 Pegasus is an open-source implementationof the DMTF CIM and WBEM standards. It is designed to be por
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    // Either a "<...>" or content begins next:    if (*_current == '<')    {        _current++;        _getElement(_current, entry);        if (nullTerminator)            *nullTerminator = '\0';        if (entry.type == XmlEntry::START_TAG)        {            if (_stack.isEmpty() && _foundRoot)                throw XmlException(XmlException::MULTIPLE_ROOTS, _line);            _foundRoot = true;            _stack.push((char*)entry.text);        }        else if (entry.type == XmlEntry::END_TAG)        {            if (_stack.isEmpty())                throw XmlException(XmlException::START_END_MISMATCH, _line);            if (strcmp(_stack.top(), entry.text) != 0)                throw XmlException(XmlException::START_END_MISMATCH, _line);            _stack.pop();        }        return true;    }    else    {        // Normalize the content:        char* start;        _normalize(_line, _current, '<', start);        // Get the content:        entry.type = XmlEntry::CONTENT;        entry.text = start;        // Overwrite '<' with a null character (temporarily).        _restoreChar = *_current;        *_current = '\0';        if (nullTerminator)            *nullTerminator = '\0';        return true;    }}void XmlParser::putBack(XmlEntry& entry){    _putBackStack.push(entry);}XmlParser::~XmlParser(){    // Nothing to do!}// A-Za-z0-9_-:.static unsigned char _isInnerElementChar[] ={    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,    1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};Boolean XmlParser::_getElementName(char*& p){    if (!CharSet::isAlNumUnder(Uint8(*p)))        throw XmlException(XmlException::BAD_START_TAG, _line);    p++;    while (*p && _isInnerElementChar[Uint8(*p)])        p++;    // The next character must be a space:    if (_isspace(*p))    {        *p++ = '\0';        _skipWhitespace(_line, p);    }    if (*p == '>')    {        *p++ = '\0';        return true;    }    return false;}Boolean XmlParser::_getOpenElementName(char*& p, Boolean& openCloseElement){    openCloseElement = false;    if (!CharSet::isAlNumUnder(Uint8(*p)))        throw XmlException(XmlException::BAD_START_TAG, _line);    p++;    while (*p && _isInnerElementChar[Uint8(*p)])        p++;    // The next character must be a space:    if (_isspace(*p))    {        *p++ = '\0';        _skipWhitespace(_line, p);    }    if (*p == '>')    {        *p++ = '\0';        return true;    }    if (p[0] == '/' && p[1] == '>')    {        openCloseElement = true;        *p = '\0';        p += 2;        return true;    }    return false;}void XmlParser::_getAttributeNameAndEqual(char*& p){    if (!CharSet::isAlNumUnder((Uint8)*p))        throw XmlException(XmlException::BAD_ATTRIBUTE_NAME, _line);    p++;    while (*p && _isInnerElementChar[Uint8(*p)])        p++;    char* term = p;    _skipWhitespace(_line, p);    if (*p != '=')        throw XmlException(XmlException::BAD_ATTRIBUTE_NAME, _line);    p++;    _skipWhitespace(_line, p);    *term = '\0';}void XmlParser::_getComment(char*& p){    // Now p points to first non-whitespace character beyond "<--" sequence:    for (; *p; p++)    {        if (p[0] == '-' && p[1] == '-')        {            if (p[2] != '>')            {                throw XmlException(                    XmlException::MINUS_MINUS_IN_COMMENT, _line);            }            // Find end of comment (excluding whitespace):            *p = '\0';            p += 3;            return;        }    }    // If it got this far, then the comment is unterminated:    throw XmlException(XmlException::UNTERMINATED_COMMENT, _line);}void XmlParser::_getCData(char*& p){    // At this point p points one past "<![CDATA[" sequence:    for (; *p; p++)    {        if (p[0] == ']' && p[1] == ']' && p[2] == '>')        {            *p = '\0';            p += 3;            return;        }        else if (*p == '\n')            _line++;    }    // If it got this far, then the comment is unterminated:    throw XmlException(XmlException::UNTERMINATED_CDATA, _line);}void XmlParser::_getDocType(char*& p){    // Just ignore the DOCTYPE command for now:    for (; *p && *p != '>'; p++)    {        if (*p == '\n')            _line++;    }    if (*p != '>')        throw XmlException(XmlException::UNTERMINATED_DOCTYPE, _line);    p++;}void XmlParser::_getElement(char*& p, XmlEntry& entry){    entry.attributeCount = 0;    //--------------------------------------------------------------------------    // Get the element name (expect one of these: '?', '!', [A-Za-z_])    //--------------------------------------------------------------------------    if (*p == '?')    {        entry.type = XmlEntry::XML_DECLARATION;        entry.text = ++p;        Boolean openCloseElement = false;        if (_getElementName(p))            return;    }    else if (*p == '!')    {        p++;        // Expect a comment or CDATA:        if (p[0] == '-' && p[1] == '-')        {            p += 2;            entry.type = XmlEntry::COMMENT;            entry.text = p;            _getComment(p);            return;        }        else if (memcmp(p, "[CDATA[", 7) == 0)        {            p += 7;            entry.type = XmlEntry::CDATA;            entry.text = p;            _getCData(p);            return;        }        else if (memcmp(p, "DOCTYPE", 7) == 0)        {            entry.type = XmlEntry::DOCTYPE;            entry.text = "";            _getDocType(p);            return;        }        throw(XmlException(XmlException::EXPECTED_COMMENT_OR_CDATA, _line));    }    else if (*p == '/')    {        entry.type = XmlEntry::END_TAG;        entry.text = ++p;        if (!_getElementName(p))            throw(XmlException(XmlException::BAD_END_TAG, _line));        return;    }    else if ((((*p >= 'A') && (*p <= 'Z')) ||              ((*p >= 'a') && (*p <= 'z')) ||              (*p == '_')))    {        entry.type = XmlEntry::START_TAG;        entry.text = p;        Boolean openCloseElement = false;        if (_getOpenElementName(p, openCloseElement))        {            if (openCloseElement)                entry.type = XmlEntry::EMPTY_TAG;            return;        }    }    else        throw XmlException(XmlException::BAD_START_TAG, _line);    //--------------------------------------------------------------------------    // Grab all the attributes:    //--------------------------------------------------------------------------    for (;;)    {        if (entry.type == XmlEntry::XML_DECLARATION)        {            if (p[0] == '?' && p[1] == '>')            {                p += 2;                return;            }        }        else if (entry.type == XmlEntry::START_TAG && p[0] == '/' && p[1] =='>')        {            entry.type = XmlEntry::EMPTY_TAG;            p += 2;            return;        }        else if (*p == '>')        {            p++;            return;        }        XmlAttribute attr;        attr.name = p;        _getAttributeNameAndEqual(p);        // Get the attribute value (e.g., "some value")        {            if ((*p != '"') && (*p != '\''))            {                throw XmlException(XmlException::BAD_ATTRIBUTE_VALUE, _line);            }            char quote = *p++;            char* start;            _normalize(_line, p, quote, start);            attr.value = start;            if (*p != quote)            {                throw XmlException(XmlException::BAD_ATTRIBUTE_VALUE, _line);            }            // Overwrite the closing quote with a null-terminator:            *p++ = '\0';        }        if (entry.type == XmlEntry::XML_DECLARATION)        {            // The next thing must a space or a "?>":            if (!(p[0] == '?' && p[1] == '>') && !_isspace(*p))            {                throw XmlException(                    XmlException::BAD_ATTRIBUTE_VALUE, _line);            }        }        else if (!(*p == '>' || (p[0] == '/' && p[1] == '>') || _isspace(*p)))        {            // The next thing must be a space or a '>':            throw XmlException(XmlException::BAD_ATTRIBUTE_VALUE, _line);        }        _skipWhitespace(_line, p);        if (entry.attributeCount == XmlEntry::MAX_ATTRIBUTES)            throw XmlException(XmlException::TOO_MANY_ATTRIBUTES, _line);        entry.attributes[entry.attributeCount++] = attr;    }}static const char* _typeStrings[] ={    "XML_DECLARATION",    "START_TAG",    "EMPTY_TAG",    "END_TAG",    "COMMENT",    "CDATA",    "DOCTYPE",    "CONTENT"};void XmlEntry::print() const{    PEGASUS_STD(cout) << "=== " << _typeStrings[type] << " ";    Boolean needQuotes = type == XmlEntry::CDATA || type == XmlEntry::CONTENT;    if (needQuotes)        PEGASUS_STD(cout) << "\"";    _printValue(text);    if (needQuotes)        PEGASUS_STD(cout) << "\"";    PEGASUS_STD(cout) << '\n';    for (Uint32 i = 0; i < attributeCount; i++)    {        PEGASUS_STD(cout) << "    " << attributes[i].name << "=\"";        _printValue(attributes[i].value);        PEGASUS_STD(cout) << "\"" << PEGASUS_STD(endl);    }}const XmlAttribute* XmlEntry::findAttribute(    const char* name) const{    for (Uint32 i = 0; i < attributeCount; i++)    {        if (strcmp(attributes[i].name, name) == 0)            return &attributes[i];    }    return 0;}// Find first non-whitespace character (set first) and last non-whitespace// character (set last one past this). For example, consider this string:////      "   87     "//// The first pointer would point to '8' and the last pointer woudl point one// beyond '7'.static void _findEnds(    const char* str,    const char*& first,    const char*& last){    first = str;    while (_isspace(*first))        first++;    if (!*first)    {        last = first;        return;    }    last = first + strlen(first);    while (last != first && _isspace(last[-1]))        last--;}Boolean XmlEntry::getAttributeValue(    const char* name,    Uint32& value) const{    const XmlAttribute* attr = findAttribute(name);    if (!attr)        return false;    const char* first;    const char* last;    _findEnds(attr->value, first, last);    char* end = 0;    long tmp = strtol(first, &end, 10);    if (!end || end != last)        return false;    value = Uint32(tmp);    return true;}Boolean XmlEntry::getAttributeValue(    const char* name,    Real32& value) const{    const XmlAttribute* attr = findAttribute(name);    if (!attr)        return false;    const char* first;    const char* last;    _findEnds(attr->value, first, last);    char* end = 0;    double tmp = strtod(first, &end);    if (!end || end != last)        return false;    value = static_cast<Real32>(tmp);    return true;}Boolean XmlEntry::getAttributeValue(    const char* name,    const char*& value) const{    const XmlAttribute* attr = findAttribute(name);    if (!attr)        return false;    value = attr->value;    return true;}Boolean XmlEntry::getAttributeValue(const char* name, String& value) const{    const char* tmp;    if (!getAttributeValue(name, tmp))        return false;    value = String(tmp);    return true;}void XmlAppendCString(Buffer& out, const char* str){    out.append(str, static_cast<Uint32>(strlen(str)));}PEGASUS_NAMESPACE_END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -