?? xmlurl.cpp
字號:
// 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 + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -