Example #1
0
Boolean XmlParser::_next(
    XmlEntry& entry,
    Boolean includeComment)
{
    if (!_putBackStack.isEmpty())
    {
        entry = _putBackStack.top();
        _putBackStack.pop();
        return true;
    }

    // If a character was overwritten with a null-terminator the last
    // time this routine was called, then put back that character. Before
    // exiting of course, restore the null-terminator.

    char* nullTerminator = 0;

    if (_restoreChar && !*_current)
    {
        nullTerminator = _current;
        *_current = _restoreChar;
        _restoreChar = '\0';
    }

    entry.attributes.clear();

    if (_supportedNamespaces)
    {
        // Remove namespaces of a deeper scope level from the stack.
        while (!_nameSpaces.isEmpty() &&
               _nameSpaces.top().scopeLevel > _stack.size())
        {
            _nameSpaces.pop();
        }
    }

    // Loop until we are done with comments if includeComment is false.
    do
    {
        // Skip over any whitespace:
        _skipWhitespace(_line, _current);

        if (!*_current)
        {
            if (nullTerminator)
                *nullTerminator = '\0';

            if (!_stack.isEmpty())
                throw XmlException(XmlException::UNCLOSED_TAGS, _line);

            return false;
        }

        // 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();
            }
        }
        else
        {
            // Normalize the content:

            char* start = _current;
            Uint32 textLen;
            _normalizeElementValue(_line, _current, textLen);

            // Get the content:

            entry.type = XmlEntry::CONTENT;
            entry.text = start;
            entry.textLen = textLen;

            // Overwrite '<' with a null character (temporarily).

            _restoreChar = *_current;
            *_current = '\0';

            if (nullTerminator)
                *nullTerminator = '\0';
        }
    } while (!includeComment && entry.type == XmlEntry::COMMENT);

    if (_supportedNamespaces &&
        (entry.type == XmlEntry::START_TAG ||
         entry.type == XmlEntry::EMPTY_TAG ||
         entry.type == XmlEntry::END_TAG))
    {
        // Determine the namespace type for this entry

        if (entry.type == XmlEntry::START_TAG ||
            entry.type == XmlEntry::EMPTY_TAG)
        {
            // Process namespace declarations and determine the namespace type
            // for the attributes.

            Uint32 scopeLevel = _stack.size();
            if (entry.type == XmlEntry::EMPTY_TAG)
            {
                // Empty tags are deeper scope, but not pushed onto the stack
                scopeLevel++;
            }

            for (Uint32 i = 0, n = entry.attributes.size(); i < n; i++)
            {
                XmlAttribute& attr = entry.attributes[i];
                if ((strncmp(attr.name, "xmlns:", 6) == 0) ||
                    (strcmp(attr.name, "xmlns") == 0))
                {
                    // Process a namespace declaration
                    XmlNamespace ns;
                    if (attr.name[5] == ':')
                    {
                        ns.localName = attr.localName;
                    }
                    else
                    {
                        // Default name space has no local name
                        ns.localName = 0;
                    }
                    ns.extendedName = attr.value;
                    ns.scopeLevel = scopeLevel;
                    ns.type = _getSupportedNamespaceType(ns.extendedName);

                    // If the namespace is not supported, assign it a unique
                    // negative identifier.
                    if (ns.type == -1)
                    {
                        ns.type = _currentUnsupportedNSType--;
                    }

                    _nameSpaces.push(ns);
                }
                else
                {
                    // Get the namespace type for this attribute.
                    attr.nsType = _getNamespaceType(attr.name);
                }
            }
        }

        entry.nsType = _getNamespaceType(entry.text);
    }
    else
    {
        entry.nsType = -1;
    }

    return true;
}
Example #2
0
xmlChar* as_xmlname(Request& r, MethodParams& params, int index, const char* msg) {
	xmlChar* localName=r.transcode(params.as_string(index, msg ? msg : XML_LOCAL_NAME_MUST_BE_STRING));
	if(xmlValidateName(localName, 0))
		throw XmlException(0, XML_INVALID_LOCAL_NAME, localName);
	return localName;
}
Example #3
0
void XmlParser::_getElement(char*& p, XmlEntry& entry)
{
    //--------------------------------------------------------------------------
    // Get the element name (expect one of these: '?', '!', [A-Za-z_])
    //--------------------------------------------------------------------------

    if (*p == '?')
    {
        entry.type = XmlEntry::XML_DECLARATION;
        entry.text = ++p;

        if (_getElementName(p, entry.localName))
            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);
            entry.textLen = strlen(entry.text);
            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, entry.localName))
            throw(XmlException(XmlException::BAD_END_TAG, _line));

        return;
    }
    else if (CharSet::isAlphaUnder(Uint8(*p)))
    {
        entry.type = XmlEntry::START_TAG;
        entry.text = p;

        Boolean openCloseElement = false;

        if (_getOpenElementName(p, entry.localName, 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.nsType = -1;
        attr.name = p;
        _getAttributeNameAndEqual(p, attr.localName);

        // Get the attribute value (e.g., "some value")
        {
            if ((*p != '"') && (*p != '\''))
            {
                throw XmlException(XmlException::BAD_ATTRIBUTE_VALUE, _line);
            }

            char quote = *p++;

            char* start;
            _normalizeAttributeValue(_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);

        entry.attributes.append(attr);
    }
}
Example #4
0
xmlChar* as_xmlqname(Request& r, MethodParams& params, int index, const char* msg) {
	xmlChar* qname=r.transcode(params.as_string(index, msg ? msg : XML_QUALIFIED_NAME_MUST_BE_STRING));
	if(xmlValidateQName(qname, 0))
		throw XmlException(0, XML_INVALID_QUALIFIED_NAME, qname);
	return qname;
}