xmluri.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 2,222 行 · 第 1/5 页

CPP
2,222
字号
    if (index == trimmedUriSpecLen || (foundScheme && (trimmedUriSpec[index] == chPound)))    {        ThrowXMLwithMemMgr1(MalformedURLException                , XMLExcepts::XMLNUM_URI_Component_Empty                , errMsg_PATH                , fMemoryManager);    }	// two slashes means generic URI syntax, so we get the authority    XMLCh* authUriSpec = (XMLCh*) fMemoryManager->allocate    (        (trimmedUriSpecLen+1) * sizeof(XMLCh)    );//new XMLCh[trimmedUriSpecLen+1];    ArrayJanitor<XMLCh> authName(authUriSpec, fMemoryManager);    XMLString::subString(authUriSpec, trimmedUriSpec, index, trimmedUriSpecLen, fMemoryManager);    if (((index+1) < trimmedUriSpecLen) &&        XMLString::startsWith(authUriSpec, DOUBLE_SLASH))    {        index += 2;        int startPos = index;        // get authority - everything up to path, query or fragment        XMLCh testChar;        while (index < trimmedUriSpecLen)        {            testChar = trimmedUriSpec[index];            if (testChar == chForwardSlash ||                testChar == chQuestion     ||                testChar == chPound         )            {                break;            }            index++;        }        // if we found authority, parse it out, otherwise we set the        // host to empty string        if (index > startPos)        {            XMLString::subString(authUriSpec, trimmedUriSpec, startPos, index, fMemoryManager);            initializeAuthority(authUriSpec);        }        else        {            //fHost = 0;            setHost(XMLUni::fgZeroLenString);        }    }    // we need to check if index has exceed the lenght or not    if (index >= trimmedUriSpecLen)        return;    XMLCh* pathUriSpec = (XMLCh*) fMemoryManager->allocate    (        (trimmedUriSpecLen+1) * sizeof(XMLCh)    );//new XMLCh[trimmedUriSpecLen+1];    ArrayJanitor<XMLCh> pathUriSpecName(pathUriSpec, fMemoryManager);    XMLString::subString(pathUriSpec, trimmedUriSpec, index, trimmedUriSpecLen, fMemoryManager);	initializePath(pathUriSpec);	// Resolve relative URI to base URI - see RFC 2396 Section 5.2	// In some cases, it might make more sense to throw an exception	// (when scheme is specified is the string spec and the base URI	// is also specified, for example), but we're just following the	// RFC specifications	if ( baseURI )    {        // check to see if this is the current doc - RFC 2396 5.2 #2        // note that this is slightly different from the RFC spec in that        // we don't include the check for query string being null        // - this handles cases where the urispec is just a query        // string or a fragment (e.g. "?y" or "#s") -        // see <http://www.ics.uci.edu/~fielding/url/test1.html> which        // identified this as a bug in the RFC        if ((!fPath || !*fPath) &&            fScheme == 0 &&            fHost == 0 && fRegAuth == 0)        {            fScheme = XMLString::replicate(baseURI->getScheme(), fMemoryManager);            fMemoryManager->deallocate(fUserInfo);//delete [] fUserInfo;            fUserInfo = XMLString::replicate(baseURI->getUserInfo(), fMemoryManager);            fHost = XMLString::replicate(baseURI->getHost(), fMemoryManager);            fPort = baseURI->getPort();            fRegAuth = XMLString::replicate(baseURI->getRegBasedAuthority(), fMemoryManager);            fMemoryManager->deallocate(fPath);//delete [] fPath;            fPath = XMLString::replicate(baseURI->getPath(), fMemoryManager);            if ( !fQueryString )            {                fQueryString = XMLString::replicate(baseURI->getQueryString(), fMemoryManager);            }            return;        }        // check for scheme - RFC 2396 5.2 #3        // if we found a scheme, it means absolute URI, so we're done        if (fScheme == 0)        {            fScheme = XMLString::replicate(baseURI->getScheme(), fMemoryManager);        }        else        {            return;        }        // check for authority - RFC 2396 5.2 #4        // if we found a host, then we've got a network path, so we're done        if (fHost == 0 && fRegAuth == 0)        {            fMemoryManager->deallocate(fUserInfo);//delete [] fUserInfo;            fUserInfo = XMLString::replicate(baseURI->getUserInfo(), fMemoryManager);            fHost = XMLString::replicate(baseURI->getHost(), fMemoryManager);            fPort = baseURI->getPort();            fRegAuth = XMLString::replicate(baseURI->getRegBasedAuthority(), fMemoryManager);        }        else        {            return;        }        // check for absolute path - RFC 2396 5.2 #5        if ((fPath && *fPath) &&            XMLString::startsWith(fPath, SINGLE_SLASH))        {            return;        }        // if we get to this point, we need to resolve relative path        // RFC 2396 5.2 #6        XMLCh* basePath = XMLString::replicate(baseURI->getPath(), fMemoryManager);        ArrayJanitor<XMLCh> basePathName(basePath, fMemoryManager);        int bufLen = trimmedUriSpecLen+XMLString::stringLen(fPath)+XMLString::stringLen(basePath)+1;        XMLCh* path = (XMLCh*) fMemoryManager->allocate(bufLen * sizeof(XMLCh));//new XMLCh[bufLen];        ArrayJanitor<XMLCh> pathName(path, fMemoryManager);        path[0] = 0;        XMLCh* tmp1 = (XMLCh*) fMemoryManager->allocate(bufLen * sizeof(XMLCh));//new XMLCh[bufLen];        ArrayJanitor<XMLCh> tmp1Name(tmp1, fMemoryManager);        XMLCh* tmp2 = (XMLCh*) fMemoryManager->allocate(bufLen * sizeof(XMLCh));//new XMLCh[bufLen];        ArrayJanitor<XMLCh> tmp2Name(tmp2, fMemoryManager);        // 6a - get all but the last segment of the base URI path        if (basePath)        {            int lastSlash = XMLString::lastIndexOf(basePath, chForwardSlash);            if (lastSlash != -1)            {                XMLString::subString(path, basePath, 0, lastSlash+1, fMemoryManager);            }        }        // 6b - append the relative URI path        XMLString::catString(path, fPath);        // 6c - remove all "./" where "." is a complete path segment        index = -1;        while ((index = XMLString::patternMatch(path, SLASH_DOT_SLASH)) != -1)        {            XMLString::subString(tmp1, path, 0, index, fMemoryManager);            XMLString::subString(tmp2, path, index+2, XMLString::stringLen(path), fMemoryManager);            path[0] = 0;            XMLString::catString(path, tmp1);            XMLString::catString(path, tmp2);        }        // 6d - remove "." if path ends with "." as a complete path segment        if (XMLString::endsWith(path, SLASH_DOT))        {            path[XMLString::stringLen(path) - 1] = chNull;        }        // 6e - remove all "<segment>/../" where "<segment>" is a complete        // path segment not equal to ".."        index = -1;        int segIndex = -1;        int offset = 1;        while ((index = XMLString::patternMatch(&(path[offset]), SLASH_DOTDOT_SLASH)) != -1)        {			// Undo offset			index += offset;			// Find start of <segment> within substring ending at found point.			XMLString::subString(tmp1, path, 0, index-1, fMemoryManager);			segIndex = XMLString::lastIndexOf(tmp1, chForwardSlash);			// Ensure <segment> exists and != ".."            if (segIndex != -1                &&                (path[segIndex+1] != chPeriod ||                 path[segIndex+2] != chPeriod ||				 segIndex + 3 != index))            {                XMLString::subString(tmp1, path, 0, segIndex, fMemoryManager);                XMLString::subString(tmp2, path, index+3, XMLString::stringLen(path), fMemoryManager);                path[0] = 0;                XMLString::catString(path, tmp1);                XMLString::catString(path, tmp2);                offset = (segIndex == 0 ? 1 : segIndex);            }            else            {                offset += 4;            }        }// while        // 6f - remove ending "<segment>/.." where "<segment>" is a        // complete path segment        if (XMLString::endsWith(path, SLASH_DOTDOT))        {			// Find start of <segment> within substring ending at found point.            index = XMLString::stringLen(path) - 3;			XMLString::subString(tmp1, path, 0, index-1, fMemoryManager);			segIndex = XMLString::lastIndexOf(tmp1, chForwardSlash);            if (segIndex != -1                &&                (path[segIndex+1] != chPeriod ||                 path[segIndex+2] != chPeriod ||				 segIndex + 3 != index))            {                path[segIndex+1] = chNull;            }        }        if (getPath())            fMemoryManager->deallocate(fPath);//delete [] fPath;        fPath = XMLString::replicate(path, fMemoryManager);    }}// ---------------------------------------------------------------------------//  Components initialization// ---------------------------------------------------------------------------//// authority     = server | reg_name// server        = [ [ userinfo "@" ] hostport ]// hostport      = host [ ":" port ]//// reg_name      = 1*( unreserved | escaped | "$" | "," |//                    ";" | ":" | "@" | "&" | "=" | "+" )//// userinfo      = *( unreserved | escaped |//                 ";" | ":" | "&" | "=" | "+" | "$" | "," )//void XMLUri::initializeAuthority(const XMLCh* const uriSpec){    int index = 0;    int start = 0;    const int end = XMLString::stringLen(uriSpec);    //    // server = [ [ userinfo "@" ] hostport ]    // userinfo is everything up @,    //    XMLCh* userinfo = (XMLCh*) fMemoryManager->allocate    (        (end+1) * sizeof(XMLCh)    );//new XMLCh[end+1];    ArrayJanitor<XMLCh> userName(userinfo, fMemoryManager);    index = XMLString::indexOf(&(uriSpec[start]), chAt);    if ( index != -1)    {        XMLString::subString(userinfo, &(uriSpec[start]), 0, index, fMemoryManager);        index++; // skip the @        start += index;    }    else    {        userinfo = 0;    }    //    // hostport = host [ ":" port ]    // host is everything up to ':', or up to     // and including ']' if followed by ':'.    //    XMLCh* host = (XMLCh*) fMemoryManager->allocate    (        (end+1) * sizeof(XMLCh)    );//new XMLCh[end+1];    ArrayJanitor<XMLCh> hostName(host, fMemoryManager);        // Search for port boundary.    if (start < end && uriSpec[start] == chOpenSquare)    {    	index = XMLString::indexOf(&(uriSpec[start]), chCloseSquare);    	if (index != -1)    	{            // skip the ']'            index = ((start + index + 1) < end               && uriSpec[start + index + 1] == chColon) ? index+1 : -1;    	}    }    else    {        index = XMLString::indexOf(&(uriSpec[start]), chColon);    }    if ( index != -1 )    {        XMLString::subString(host, &(uriSpec[start]), 0, index, fMemoryManager);        index++;  // skip the :        start +=index;    }    else    {        XMLString::subString(host, &(uriSpec[start]), 0, end-start, fMemoryManager);        start = end;    }    // port is everything after ":"    XMLCh* portStr = (XMLCh*) fMemoryManager->allocate    (        (end+1) * sizeof(XMLCh)    );//new XMLCh[end+1];    ArrayJanitor<XMLCh> portName(portStr, fMemoryManager);    int port = -1;    if ((host && *host) &&   // non empty host        (index != -1)                    &&   // ":" found        (start < end)                     )   // ":" is not the last    {        XMLString::subString(portStr, &(uriSpec[start]), 0, end-start, fMemoryManager);        if (portStr && *portStr)        {            try            {                port = XMLString::parseInt(portStr, fMemoryManager);            }            catch(const OutOfMemoryException&)            {                throw;            }            catch (...)            {                throw;            }        }    } // if > 0    // Check if we have server based authority.    if (isValidServerBasedAuthority(host, port, userinfo, fMemoryManager))    {        if (fHost)            fMemoryManager->deallocate(fHost);//delete [] fHost;                if (fUserInfo)            fMemoryManager->deallocate(fUserInfo);//delete[] fUserInfo;                    fHost = XMLString::replicate(host, fMemoryManager);        fPort = port;        fUserInfo = XMLString::replicate(userinfo, fMemoryManager);                return;    }    // This must be registry based authority or the URI is malformed.    setRegBasedAuthority(uriSpec);}// scheme = alpha *( alpha | digit | "+" | "-" | "." )void XMLUri::initializeScheme(const XMLCh* const uriSpec){    const XMLCh* tmpPtr = XMLString::findAny(uriSpec, SCHEME_SEPARATORS);    if ( !tmpPtr )    {        ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::XMLNUM_URI_No_Scheme, fMemoryManager);    }	else    {        XMLCh* scheme = (XMLCh*) fMemoryManager->allocate        (            (XMLString::stringLen(uriSpec) + 1) * sizeof(XMLCh)        );//new XMLCh[XMLString::stringLen(uriSpec)+1];        ArrayJanitor<XMLCh> tmpName(scheme, fMemoryManager);        XMLString::subString(scheme, uriSpec, 0, (tmpPtr - uriSpec), fMemoryManager);        setScheme(scheme);	}}void XMLUri::initializePath(const XMLCh* const uriSpec){    if ( !uriSpec )    {        ThrowXMLwithMemMgr1(MalformedURLException                , XMLExcepts::XMLNUM_URI_Component_Empty                , errMsg_PATH                , fMemoryManager);    }    int index = 0;    int start = 0;    int end = XMLString::stringLen(uriSpec);    XMLCh testChar;    // 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 ||                        !XMLString::isHex(uriSpec[index+1]) ||                        !XMLString::isHex(uriSpec[index+2]))                    {                        XMLCh value1[BUF_LEN+1];                        XMLString::moveChars(value1, &(uriSpec[index]), 3);                        value1[3] = chNull;                        ThrowXMLwithMemMgr2(MalformedURLException                                , XMLExcepts::XMLNUM_URI_Component_Invalid_EscapeSequence                                , errMsg_PATH                                , value1                                , fMemoryManager);

⌨️ 快捷键说明

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