void XMLUri::initializePath()

in src/xercesc/util/XMLUri.cpp [826:1111]


void XMLUri::initializePath(const XMLCh* const uriSpec)
{
    if ( !uriSpec )
    {
        ThrowXMLwithMemMgr1(MalformedURLException
                , XMLExcepts::XMLNUM_URI_Component_Empty
                , errMsg_PATH
                , fMemoryManager);
    }

    XMLSize_t index = 0;
    XMLSize_t start = 0;
    XMLSize_t end = XMLString::stringLen(uriSpec);
    XMLCh testChar = 0;

    // path - everything up to query string or fragment
    if (start < end)
    {
        // RFC 2732 only allows '[' and ']' to appear in the opaque part.
        if (!getScheme() || uriSpec[start] == chForwardSlash)
        {
            // Scan path.
            // abs_path = "/"  path_segments
            // rel_path = rel_segment [ abs_path ]
            while (index < end)
            {
                testChar = uriSpec[index];
                if (testChar == chQuestion || testChar == chPound)
                {
                    break;
                }

                // check for valid escape sequence
                if (testChar == chPercent)
                {
                    if (index + 2 >= end)
                    {
                        XMLCh value1[3];
                        value1[1] = chNull;
                        value1[2] = chNull;
                        XMLString::moveChars(value1, &(uriSpec[index]), (index + 1 >= end ? 1 : 2));
                        ThrowXMLwithMemMgr2(MalformedURLException
                            , XMLExcepts::XMLNUM_URI_Component_Invalid_EscapeSequence
                            , errMsg_PATH
                            , value1
                            , fMemoryManager);
                    }
                    else if (!XMLString::isHex(uriSpec[index+1]) || !XMLString::isHex(uriSpec[index+2]))
                    {
                        XMLCh value1[4];
                        XMLString::moveChars(value1, &(uriSpec[index]), 3);
                        value1[3] = chNull;
                        ThrowXMLwithMemMgr2(MalformedURLException
                                , XMLExcepts::XMLNUM_URI_Component_Invalid_EscapeSequence
                                , errMsg_PATH
                                , value1
                                , fMemoryManager);
                    }
                }
                else if (!isUnreservedCharacter(testChar) &&
                         !isPathCharacter(testChar))
                {
                    XMLCh value1[2];
                    value1[0] = testChar;
                    value1[1] = chNull;
                    ThrowXMLwithMemMgr2(MalformedURLException
                            , XMLExcepts::XMLNUM_URI_Component_Invalid_Char
                            , errMsg_PATH
                            , value1
                            , fMemoryManager);
                }

                index++;
            }//while (index < end)
        }
        else
        {
            // Scan opaque part.
            // opaque_part = uric_no_slash *uric
            while (index < end)
            {
                testChar = uriSpec[index];
                if (testChar == chQuestion || testChar == chPound)
                {
                    break;
                }

                // check for valid escape sequence
                if (testChar == chPercent)
                {
                    if (index + 2 >= end)
                    {
                        XMLCh value1[3];
                        value1[1] = chNull;
                        value1[2] = chNull;
                        XMLString::moveChars(value1, &(uriSpec[index]), (index + 1 >= end ? 1 : 2));
                        ThrowXMLwithMemMgr2(MalformedURLException
                            , XMLExcepts::XMLNUM_URI_Component_Invalid_EscapeSequence
                            , errMsg_PATH
                            , value1
                            , fMemoryManager);
                    }
                    else if (!XMLString::isHex(uriSpec[index+1]) || !XMLString::isHex(uriSpec[index+2]))
                    {
                        XMLCh value1[4];
                        XMLString::moveChars(value1, &(uriSpec[index]), 3);
                        value1[3] = chNull;
                        ThrowXMLwithMemMgr2(MalformedURLException
                                , XMLExcepts::XMLNUM_URI_Component_Invalid_EscapeSequence
                                , errMsg_PATH
                                , value1
                                , fMemoryManager);
                    }
                }
                // If the scheme specific part is opaque, it can contain '['
                // and ']'. uric_no_slash wasn't modified by RFC 2732, which
                // I've interpreted as an error in the spec, since the
                // production should be equivalent to (uric - '/'), and uric
                // contains '[' and ']'.
                else if (!isReservedOrUnreservedCharacter(testChar))
                {
                    XMLCh value1[2];
                    value1[0] = testChar;
                    value1[1] = chNull;
                    ThrowXMLwithMemMgr2(MalformedURLException
                            , XMLExcepts::XMLNUM_URI_Component_Invalid_Char
                            , errMsg_PATH
                            , value1
                            , fMemoryManager);
                }

                index++;
            }//while (index < end)
        }
    } //if (start < end)

    if (getPath())
    {
        fMemoryManager->deallocate(fPath);//delete [] fPath;
    }

    fPath = (XMLCh*) fMemoryManager->allocate((index+1) * sizeof(XMLCh));//new XMLCh[index+1];
    XMLString::subString(fPath, uriSpec, start, index, fMemoryManager);

    // query - starts with ? and up to fragment or end
    if (testChar == chQuestion)
    {
        index++;
        start = index;
        while (index < end)
        {
            testChar = uriSpec[index];
            if (testChar == chPound)
            {
                break;
            }

            if (testChar == chPercent)
            {
                if (index + 2 >= end)
                {
                    XMLCh value1[3];
                    value1[1] = chNull;
                    value1[2] = chNull;
                    XMLString::moveChars(value1, &(uriSpec[index]), (index + 1 >= end ? 1 : 2));
                    ThrowXMLwithMemMgr2(MalformedURLException
                        , XMLExcepts::XMLNUM_URI_Component_Invalid_EscapeSequence
                        , errMsg_QUERY
                        , value1
                        , fMemoryManager);
                }
                if (!XMLString::isHex(uriSpec[index+1]) || !XMLString::isHex(uriSpec[index+2]))
                {
                    XMLCh value1[4];
                    XMLString::moveChars(value1, &(uriSpec[index]), 3);
                    value1[3] = chNull;
                    ThrowXMLwithMemMgr2(MalformedURLException
                            , XMLExcepts::XMLNUM_URI_Component_Invalid_EscapeSequence
                            , errMsg_QUERY
                            , value1
                            , fMemoryManager);
                }
            }
            else if (!isReservedOrUnreservedCharacter(testChar))
            {
                XMLCh value1[2];
                value1[0] = testChar;
                value1[1] = chNull;
                ThrowXMLwithMemMgr2(MalformedURLException
                        , XMLExcepts::XMLNUM_URI_Component_Invalid_Char
                        , errMsg_QUERY
                        , value1
                        , fMemoryManager);
            }
            index++;
        }

        if (getQueryString())
        {
            fMemoryManager->deallocate(fQueryString);//delete [] fQueryString;
        }

        fQueryString = (XMLCh*) fMemoryManager->allocate
        (
            (index - start + 1) * sizeof(XMLCh)
        );//new XMLCh[index - start + 1];
        XMLString::subString(fQueryString, uriSpec, start, index, fMemoryManager);
    }

    // fragment - starts with #
    if (testChar == chPound)
    {
        index++;
        start = index;
        while (index < end)
        {
            testChar = uriSpec[index];

            if (testChar == chPercent)
            {
                if (index + 2 >= end)
                {
                    XMLCh value1[3];
                    value1[1] = chNull;
                    value1[2] = chNull;
                    XMLString::moveChars(value1, &(uriSpec[index]), (index + 1 >= end ? 1 : 2));
                    ThrowXMLwithMemMgr2(MalformedURLException
                        , XMLExcepts::XMLNUM_URI_Component_Invalid_EscapeSequence
                        , errMsg_FRAGMENT
                        , value1
                        , fMemoryManager);
                }
                if (!XMLString::isHex(uriSpec[index+1]) || !XMLString::isHex(uriSpec[index+2]))
                {
                    XMLCh value1[4];
                    XMLString::moveChars(value1, &(uriSpec[index]), 3);
                    value1[3] = chNull;
                    ThrowXMLwithMemMgr2(MalformedURLException
                            , XMLExcepts::XMLNUM_URI_Component_Invalid_EscapeSequence
                            , errMsg_FRAGMENT
                            , value1
                            , fMemoryManager);
                }
            }
            else if (!isReservedOrUnreservedCharacter(testChar))
            {
                XMLCh value1[2];
                value1[0] = testChar;
                value1[1] = chNull;
                ThrowXMLwithMemMgr2(MalformedURLException
                        , XMLExcepts::XMLNUM_URI_Component_Invalid_Char
                        , errMsg_FRAGMENT
                        , value1
                        , fMemoryManager);
            }

            index++;

        }

        if (getFragment())
            fMemoryManager->deallocate(fFragment);//delete [] fFragment;

        //make sure that there is something following the '#'
        if (index > start)
        {
            fFragment = (XMLCh*) fMemoryManager->allocate
            (
                (index - start + 1) * sizeof(XMLCh)
            );//new XMLCh[index - start + 1];
            XMLString::subString(fFragment, uriSpec, start, index, fMemoryManager);
        }
        else
        {
            // RFC 2396, 4.0. URI Reference
            // URI-reference = [absoulteURI | relativeURI] [# fragment]
            //
            // RFC 2396, 4.1. Fragment Identifier
            // fragment = *uric
            //
            // empty fragment is valid
            fFragment = 0;
        }
    }

}