xmlurl.cpp

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

CPP
1,467
字号
	//  parse the base URL string and conglomerate them.	//	if (isRelative() && baseURL)	{		if (*baseURL)		{			XMLURL basePart(baseURL, fMemoryManager);			if (!conglomerateWithBase(basePart, false))			{				cleanup();				ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_RelativeBaseURL, fMemoryManager);			}		}	}}// this version of setURL doesn't throw a malformedurl exception// instead it returns false when it failed (or when it would of// thrown a malformedurl exception)bool XMLURL::setURL(const XMLCh* const    baseURL                  , const XMLCh* const    relativeURL                  , XMLURL& xmlURL){    cleanup();    // Parse our URL string    if (parse(relativeURL, xmlURL))    {	    //  If its relative and the base is non-null and non-empty, then	    //  parse the base URL string and conglomerate them.	    //	    if (isRelative() && baseURL && *baseURL)	    {		   	        XMLURL basePart(fMemoryManager);            if (parse(baseURL, basePart)  && conglomerateWithBase(basePart, false))            {    		        return true;			                    		    }	    }        else            return true;    }    return false;}void XMLURL::setURL(const XMLURL&         baseURL                  , const XMLCh* const    relativeURL){    cleanup();	// Parse our URL string    parse(relativeURL);    // If its relative, then conglomerate with the base URL    if (isRelative())		conglomerateWithBase(baseURL);}// ---------------------------------------------------------------------------//  XMLURL: Miscellaneous methods// ---------------------------------------------------------------------------bool XMLURL::isRelative() const{    // If no protocol then relative    if (fProtocol == Unknown)        return true;    // If no path, or the path is not absolute, then relative    if (!fPath)        return true;    if (*fPath != chForwardSlash)        return true;    return false;}bool XMLURL::hasInvalidChar() const {    return fHasInvalidChar;}BinInputStream* XMLURL::makeNewStream() const{    //    //  If its a local host, then we short circuit it and use our own file    //  stream support. Otherwise, we just let it fall through and let the    //  installed network access object provide a stream.    //    if (fProtocol == XMLURL::File)    {        if (!fHost || !XMLString::compareIString(fHost, XMLUni::fgLocalHostString))        {            XMLCh* realPath = XMLString::replicate(fPath, fMemoryManager);            ArrayJanitor<XMLCh> basePathName(realPath, fMemoryManager);            //            // Need to manually replace any character reference %xx first            // HTTP protocol will be done automatically by the netaccessor            //            int end = XMLString::stringLen(realPath);            int percentIndex = XMLString::indexOf(realPath, chPercent, 0, fMemoryManager);            while (percentIndex != -1) {                if (percentIndex+2 >= end ||                    !isHexDigit(realPath[percentIndex+1]) ||                    !isHexDigit(realPath[percentIndex+2]))                {                    XMLCh value1[4];                    XMLString::moveChars(value1, &(realPath[percentIndex]), 3);                    value1[3] = chNull;                    ThrowXMLwithMemMgr2(MalformedURLException                            , XMLExcepts::XMLNUM_URI_Component_Invalid_EscapeSequence                            , realPath                            , value1                            , fMemoryManager);                }                unsigned int value = (xlatHexDigit(realPath[percentIndex+1]) * 16) + xlatHexDigit(realPath[percentIndex+2]);                realPath[percentIndex] = XMLCh(value);                int i =0;                for (i = percentIndex + 1; i < end - 2 ; i++)                    realPath[i] = realPath[i+2];                realPath[i] = chNull;                end = i;                percentIndex = XMLString::indexOf(realPath, chPercent, percentIndex, fMemoryManager);            }            BinFileInputStream* retStrm = new (fMemoryManager) BinFileInputStream(realPath);            if (!retStrm->getIsOpen())            {                delete retStrm;                return 0;            }            return retStrm;        }    }    //    //  If we don't have have an installed net accessor object, then we    //  have to just throw here.    //    if (!XMLPlatformUtils::fgNetAccessor)        ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_UnsupportedProto, fMemoryManager);    // Else ask the net accessor to create the stream    return XMLPlatformUtils::fgNetAccessor->makeNew(*this);}void XMLURL::makeRelativeTo(const XMLCh* const baseURLText){    // If this one is not relative, don't bother    if (!isRelative())        return;    XMLURL baseURL(baseURLText, fMemoryManager);    conglomerateWithBase(baseURL);}void XMLURL::makeRelativeTo(const XMLURL& baseURL){    // If this one is not relative, don't bother    if (!isRelative())        return;    conglomerateWithBase(baseURL);}// ---------------------------------------------------------------------------//  XMLURL: Private helper methods// ---------------------------------------------------------------------------////  This method will take the broken out parts of the URL and build up the//  full text. We don't do this unless someone asks us to, since its often//  never required.//void XMLURL::buildFullText(){    // Calculate the worst case size of the buffer required    unsigned int bufSize = gMaxProtoLen + 1                           + XMLString::stringLen(fFragment) + 1                           + XMLString::stringLen(fHost) + 2                           + XMLString::stringLen(fPassword) + 1                           + XMLString::stringLen(fPath)                           + XMLString::stringLen(fQuery) + 1                           + XMLString::stringLen(fUser) + 1                           + 32;    // Clean up the existing buffer and allocate another    fMemoryManager->deallocate(fURLText);//delete [] fURLText;    fURLText = (XMLCh*) fMemoryManager->allocate((bufSize) * sizeof(XMLCh));//new XMLCh[bufSize];    *fURLText = 0;    XMLCh* outPtr = fURLText;    if (fProtocol != Unknown)    {        XMLString::catString(fURLText, getProtocolName());        outPtr += XMLString::stringLen(fURLText);        *outPtr++ = chColon;        *outPtr++ = chForwardSlash;        *outPtr++ = chForwardSlash;    }    if (fUser)    {        XMLString::copyString(outPtr, fUser);        outPtr += XMLString::stringLen(fUser);        if (fPassword)        {            *outPtr++ = chColon;            XMLString::copyString(outPtr, fPassword);            outPtr += XMLString::stringLen(fPassword);        }        *outPtr++ = chAt;    }    if (fHost)    {        XMLString::copyString(outPtr, fHost);        outPtr += XMLString::stringLen(fHost);        //        //  If the port is zero, then we don't put it in. Else we need        //  to because it was explicitly provided.        //        if (fPortNum)        {            *outPtr++ = chColon;            XMLCh tmpBuf[17];            XMLString::binToText(fPortNum, tmpBuf, 16, 10, fMemoryManager);            XMLString::copyString(outPtr, tmpBuf);            outPtr += XMLString::stringLen(tmpBuf);        }    }    if (fPath)    {        XMLString::copyString(outPtr, fPath);        outPtr += XMLString::stringLen(fPath);    }    if (fQuery)    {        *outPtr++ = chQuestion;        XMLString::copyString(outPtr, fQuery);        outPtr += XMLString::stringLen(fQuery);    }    if (fFragment)    {        *outPtr++ = chPound;        XMLString::copyString(outPtr, fFragment);        outPtr += XMLString::stringLen(fFragment);    }    // Cap it off in case the last op was not a string copy    *outPtr = 0;}////  Just a central place to handle cleanup, since its done from a number//  of different spots.//void XMLURL::cleanup(){    fMemoryManager->deallocate(fFragment);//delete [] fFragment;    fMemoryManager->deallocate(fHost);//delete [] fHost;    fMemoryManager->deallocate(fPassword);//delete [] fPassword;    fMemoryManager->deallocate(fPath);//delete [] fPath;    fMemoryManager->deallocate(fQuery);//delete [] fQuery;    fMemoryManager->deallocate(fUser);//delete [] fUser;    fMemoryManager->deallocate(fURLText);//delete [] fURLText;    fFragment = 0;    fHost = 0;    fPassword = 0;    fPath = 0;    fQuery = 0;    fUser = 0;    fURLText = 0;    fProtocol = Unknown;    fPortNum = 0;    fHasInvalidChar = false;}//This function  has been modified to take a bool parameter and the//functionality inside looks irrational but is only to make//solaris 2.7 CC 5.0 optimized build happy.bool XMLURL::conglomerateWithBase(const XMLURL& baseURL, bool useExceptions){    // The base URL cannot be relative    if (baseURL.isRelative())    {        if (useExceptions)			ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_RelativeBaseURL, fMemoryManager);        else            return false;    }    //    //  Check a special case. If all we have is a fragment, then we want    //  to just take the base host and path, plus our fragment.    //    if ((fProtocol == Unknown)    &&  !fHost    &&  !fPath    &&  fFragment)    {        // Just in case, make sure we don't leak the user or password values        fMemoryManager->deallocate(fUser);//delete [] fUser;        fUser = 0;        fMemoryManager->deallocate(fPassword);//delete [] fPassword;        fPassword = 0;        // Copy over the protocol and port number as is        fProtocol = baseURL.fProtocol;        fPortNum = baseURL.fPortNum;        // Replicate the base fields that are provided        fHost = XMLString::replicate(baseURL.fHost, fMemoryManager);        fUser = XMLString::replicate(baseURL.fUser, fMemoryManager);        fPassword = XMLString::replicate(baseURL.fPassword, fMemoryManager);        fPath = XMLString::replicate(baseURL.fPath, fMemoryManager);        return true;    }    //    //  All we have to do is run up through our fields and, for each one    //  that we don't have, use the based URL's. Once we hit one field    //  that we have, we stop.    //    if (fProtocol != Unknown)        return true;    fProtocol = baseURL.fProtocol;    //    //  If the protocol is not file, and we either already have our own    //  host, or the base does not have one, then we are done.    //    if (fProtocol != File)    {        if (fHost || !baseURL.fHost)            return true;    }    // Replicate all of the hosty stuff if the base has one    if (baseURL.fHost)    {        // Just in case, make sure we don't leak a user or password field        fMemoryManager->deallocate(fUser);//delete [] fUser;        fUser = 0;        fMemoryManager->deallocate(fPassword);//delete [] fPassword;        fPassword = 0;        fMemoryManager->deallocate(fHost);//delete [] fHost;        fHost = 0;        fHost = XMLString::replicate(baseURL.fHost, fMemoryManager);        fUser = XMLString::replicate(baseURL.fUser, fMemoryManager);        fPassword = XMLString::replicate(baseURL.fPassword, fMemoryManager);        fPortNum = baseURL.fPortNum;    }    // If we have a path and its absolute, then we are done    const bool hadPath = (fPath != 0);    if (hadPath)    {        if (*fPath == chForwardSlash)            return true;    }    // Its a relative path, so weave them together.    if (baseURL.fPath) {        XMLCh* temp = XMLPlatformUtils::weavePaths(baseURL.fPath, fPath ,fMemoryManager);        fMemoryManager->deallocate(fPath);//delete [] fPath;        fPath = temp;    }    // If we had any original path, then we are done    if (hadPath)        return true;    // We had no original path, so go on to deal with the query/fragment parts    if (fQuery || !baseURL.fQuery)        return true;    fQuery = XMLString::replicate(baseURL.fQuery, fMemoryManager);    if (fFragment || !baseURL.fFragment)        return true;    fFragment = XMLString::replicate(baseURL.fFragment, fMemoryManager);	return true;}void XMLURL::parse(const XMLCh* const urlText){    // Simplify things by checking for the psycho scenarios first    if (!*urlText)        ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_NoProtocolPresent, fMemoryManager);    // Before we start, check if this urlText contains valid uri characters    if (!XMLUri::isURIString(urlText))        fHasInvalidChar = true;    else        fHasInvalidChar = false;    //    //  The first thing we will do is to check for a file name, so that    //  we don't waste time thinking its a URL. If its in the form x:\    //  or x:/ and x is an ASCII letter, then assume that's the deal.    //    if (((*urlText >= chLatin_A) && (*urlText <= chLatin_Z))    ||  ((*urlText >= chLatin_a) && (*urlText <= chLatin_z)))    {        if (*(urlText + 1) == chColon)        {            if ((*(urlText + 2) == chForwardSlash)            ||  (*(urlText + 2) == chBackSlash))            {                ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_NoProtocolPresent, fMemoryManager);            }        }    }    // Get a copy of the URL that we can modify    XMLCh* srcCpy = XMLString::replicate(urlText, fMemoryManager);    ArrayJanitor<XMLCh> janSrcCopy(srcCpy, fMemoryManager);    //    //  Get a pointer now that we can run up thrown the source as we parse    //  bits and pieces out of it.    //    XMLCh* srcPtr = srcCpy;    // Run up past any spaces    while (*srcPtr)    {        if (!XMLPlatformUtils::fgTransService->isSpace(*srcPtr))            break;        srcPtr++;    }    // Make sure it wasn't all space    if (!*srcPtr)        ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_NoProtocolPresent, fMemoryManager);    //    //  Ok, the next thing we have to do is to find either a / or : character.    //  If the : is first, we assume we have a protocol. If the / is first,    //  then we skip to the host processing.    //    XMLCh* ptr1 = XMLString::findAny(srcPtr, gListOne);    XMLCh* ptr2;    // If we found a protocol, then deal with it    if (ptr1)    {        if (*ptr1 == chColon)        {            // Cap the string at the colon            *ptr1 = 0;            // And try to find it in our list of protocols            fProtocol = lookupByName(srcPtr);            if (fProtocol == Unknown)            {                ThrowXMLwithMemMgr1                (                    MalformedURLException                    , XMLExcepts::URL_UnsupportedProto1

⌨️ 快捷键说明

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