GME
13
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* 00019 * $Id: XMLURL.cpp 901107 2010-01-20 08:45:02Z borisk $ 00020 */ 00021 00022 00023 // --------------------------------------------------------------------------- 00024 // Includes 00025 // --------------------------------------------------------------------------- 00026 #include <xercesc/util/BinFileInputStream.hpp> 00027 #include <xercesc/util/Janitor.hpp> 00028 #include <xercesc/util/PlatformUtils.hpp> 00029 #include <xercesc/util/RuntimeException.hpp> 00030 #include <xercesc/util/TransService.hpp> 00031 #include <xercesc/util/XMLURL.hpp> 00032 #include <xercesc/util/XMLNetAccessor.hpp> 00033 #include <xercesc/util/XMLString.hpp> 00034 #include <xercesc/util/XMLUniDefs.hpp> 00035 #include <xercesc/util/XMLUni.hpp> 00036 #include <xercesc/util/XMLUri.hpp> 00037 #include <xercesc/util/OutOfMemoryException.hpp> 00038 #include <xercesc/util/XMLChar.hpp> 00039 00040 XERCES_CPP_NAMESPACE_BEGIN 00041 00042 00043 00044 // --------------------------------------------------------------------------- 00045 // Local types 00046 // 00047 // TypeEntry 00048 // This structure defines a single entry in the list of URL types. Each 00049 // entry indicates the prefix for that type of URL, and the SourceTypes 00050 // value it maps to. 00051 // --------------------------------------------------------------------------- 00052 struct ProtoEntry 00053 { 00054 XMLURL::Protocols protocol; 00055 const XMLCh* prefix; 00056 unsigned int defPort; 00057 }; 00058 00059 00060 // --------------------------------------------------------------------------- 00061 // Local data 00062 // 00063 // gXXXString 00064 // These are the strings for our prefix types. They all have to be 00065 // Unicode strings all the time, so we can't just do regular strings. 00066 // 00067 // gProtoList 00068 // The list of URL types that we support and some info related to each 00069 // one. 00070 // 00071 // gMaxProtoLen 00072 // The length of the longest protocol string 00073 // 00074 // NOTE:!!! Be sure to keep this up to date if new protocols are added! 00075 // --------------------------------------------------------------------------- 00076 static const XMLCh gFileString[] = 00077 { 00078 chLatin_f, chLatin_i, chLatin_l, chLatin_e, chNull 00079 }; 00080 00081 static const XMLCh gFTPString[] = 00082 { 00083 chLatin_f, chLatin_t, chLatin_p, chNull 00084 }; 00085 00086 static const XMLCh gHTTPString[] = 00087 { 00088 chLatin_h, chLatin_t, chLatin_t, chLatin_p, chNull 00089 }; 00090 00091 static const XMLCh gHTTPSString[] = 00092 { 00093 chLatin_h, chLatin_t, chLatin_t, chLatin_p, chLatin_s, chNull 00094 }; 00095 00096 static ProtoEntry gProtoList[XMLURL::Protocols_Count] = 00097 { 00098 { XMLURL::File , gFileString , 0 } 00099 , { XMLURL::HTTP , gHTTPString , 80 } 00100 , { XMLURL::FTP , gFTPString , 21 } 00101 , { XMLURL::HTTPS , gHTTPSString , 443 } 00102 }; 00103 00104 // !!! Keep these up to date with list above! 00105 static const unsigned int gMaxProtoLen = 5; 00106 00107 static const XMLCh gListOne[] = { chColon, chForwardSlash, chNull }; 00108 static const XMLCh gListTwo[] = { chAt, chNull }; 00109 static const XMLCh gListThree[] = { chColon, chNull }; 00110 static const XMLCh gListFour[] = { chForwardSlash, chNull }; 00111 static const XMLCh gListFive[] = { chPound, chQuestion, chNull }; 00112 static const XMLCh gListSix[] = { chPound, chNull }; 00113 00114 // --------------------------------------------------------------------------- 00115 // Local methods 00116 // --------------------------------------------------------------------------- 00117 static bool isHexDigit(const XMLCh toCheck) 00118 { 00119 if (((toCheck >= chDigit_0) && (toCheck <= chDigit_9)) 00120 || ((toCheck >= chLatin_A) && (toCheck <= chLatin_Z)) 00121 || ((toCheck >= chLatin_a) && (toCheck <= chLatin_z))) 00122 { 00123 return true; 00124 } 00125 return false; 00126 } 00127 00128 static unsigned int xlatHexDigit(const XMLCh toXlat) 00129 { 00130 if ((toXlat >= chDigit_0) && (toXlat <= chDigit_9)) 00131 return (unsigned int)(toXlat - chDigit_0); 00132 00133 if ((toXlat >= chLatin_A) && (toXlat <= chLatin_Z)) 00134 return (unsigned int)(toXlat - chLatin_A) + 10; 00135 00136 return (unsigned int)(toXlat - chLatin_a) + 10; 00137 } 00138 00139 00140 00141 // --------------------------------------------------------------------------- 00142 // XMLURL: Public, static methods 00143 // --------------------------------------------------------------------------- 00144 XMLURL::Protocols XMLURL::lookupByName(const XMLCh* const protoName) 00145 { 00146 for (unsigned int index = 0; index < XMLURL::Protocols_Count; index++) 00147 { 00148 if (!XMLString::compareIStringASCII(protoName, gProtoList[index].prefix)) 00149 return gProtoList[index].protocol; 00150 } 00151 return XMLURL::Unknown; 00152 } 00153 00154 00155 00156 // --------------------------------------------------------------------------- 00157 // XMLURL: Constructors and Destructor 00158 // --------------------------------------------------------------------------- 00159 XMLURL::XMLURL(MemoryManager* const manager) : 00160 00161 fMemoryManager(manager) 00162 , fFragment(0) 00163 , fHost(0) 00164 , fPassword(0) 00165 , fPath(0) 00166 , fPortNum(0) 00167 , fProtocol(XMLURL::Unknown) 00168 , fQuery(0) 00169 , fUser(0) 00170 , fURLText(0) 00171 , fHasInvalidChar(false) 00172 { 00173 } 00174 00175 typedef JanitorMemFunCall<XMLURL> CleanupType; 00176 00177 XMLURL::XMLURL(const XMLCh* const baseURL 00178 , const XMLCh* const relativeURL 00179 , MemoryManager* const manager) : 00180 00181 fMemoryManager(manager) 00182 , fFragment(0) 00183 , fHost(0) 00184 , fPassword(0) 00185 , fPath(0) 00186 , fPortNum(0) 00187 , fProtocol(XMLURL::Unknown) 00188 , fQuery(0) 00189 , fUser(0) 00190 , fURLText(0) 00191 , fHasInvalidChar(false) 00192 { 00193 CleanupType cleanup(this, &XMLURL::cleanUp); 00194 00195 try 00196 { 00197 setURL(baseURL, relativeURL); 00198 } 00199 catch(const OutOfMemoryException&) 00200 { 00201 cleanup.release(); 00202 00203 throw; 00204 } 00205 00206 cleanup.release(); 00207 } 00208 00209 XMLURL::XMLURL(const XMLCh* const baseURL 00210 , const char* const relativeURL 00211 , MemoryManager* const manager) : 00212 00213 fMemoryManager(manager) 00214 , fFragment(0) 00215 , fHost(0) 00216 , fPassword(0) 00217 , fPath(0) 00218 , fPortNum(0) 00219 , fProtocol(XMLURL::Unknown) 00220 , fQuery(0) 00221 , fUser(0) 00222 , fURLText(0) 00223 , fHasInvalidChar(false) 00224 { 00225 CleanupType cleanup(this, &XMLURL::cleanUp); 00226 00227 XMLCh* tmpRel = XMLString::transcode(relativeURL, fMemoryManager); 00228 ArrayJanitor<XMLCh> janRel(tmpRel, fMemoryManager); 00229 try 00230 { 00231 setURL(baseURL, tmpRel); 00232 } 00233 catch(const OutOfMemoryException&) 00234 { 00235 cleanup.release(); 00236 00237 throw; 00238 } 00239 00240 cleanup.release(); 00241 } 00242 00243 XMLURL::XMLURL(const XMLURL& baseURL 00244 , const XMLCh* const relativeURL) : 00245 00246 fMemoryManager(baseURL.fMemoryManager) 00247 , fFragment(0) 00248 , fHost(0) 00249 , fPassword(0) 00250 , fPath(0) 00251 , fPortNum(0) 00252 , fProtocol(XMLURL::Unknown) 00253 , fQuery(0) 00254 , fUser(0) 00255 , fURLText(0) 00256 , fHasInvalidChar(false) 00257 { 00258 CleanupType cleanup(this, &XMLURL::cleanUp); 00259 00260 try 00261 { 00262 setURL(baseURL, relativeURL); 00263 } 00264 catch(const OutOfMemoryException&) 00265 { 00266 cleanup.release(); 00267 00268 throw; 00269 } 00270 00271 cleanup.release(); 00272 } 00273 00274 XMLURL::XMLURL(const XMLURL& baseURL 00275 , const char* const relativeURL) : 00276 00277 fMemoryManager(baseURL.fMemoryManager) 00278 , fFragment(0) 00279 , fHost(0) 00280 , fPassword(0) 00281 , fPath(0) 00282 , fPortNum(0) 00283 , fProtocol(XMLURL::Unknown) 00284 , fQuery(0) 00285 , fUser(0) 00286 , fURLText(0) 00287 , fHasInvalidChar(false) 00288 { 00289 CleanupType cleanup(this, &XMLURL::cleanUp); 00290 00291 XMLCh* tmpRel = XMLString::transcode(relativeURL, fMemoryManager); 00292 ArrayJanitor<XMLCh> janRel(tmpRel, fMemoryManager); 00293 try 00294 { 00295 setURL(baseURL, tmpRel); 00296 } 00297 catch(const OutOfMemoryException&) 00298 { 00299 cleanup.release(); 00300 00301 throw; 00302 } 00303 00304 cleanup.release(); 00305 } 00306 00307 XMLURL::XMLURL(const XMLCh* const urlText, 00308 MemoryManager* const manager) : 00309 00310 fMemoryManager(manager) 00311 , fFragment(0) 00312 , fHost(0) 00313 , fPassword(0) 00314 , fPath(0) 00315 , fPortNum(0) 00316 , fProtocol(XMLURL::Unknown) 00317 , fQuery(0) 00318 , fUser(0) 00319 , fURLText(0) 00320 , fHasInvalidChar(false) 00321 { 00322 CleanupType cleanup(this, &XMLURL::cleanUp); 00323 00324 try 00325 { 00326 setURL(urlText); 00327 } 00328 catch(const OutOfMemoryException&) 00329 { 00330 cleanup.release(); 00331 00332 throw; 00333 } 00334 00335 cleanup.release(); 00336 } 00337 00338 XMLURL::XMLURL(const char* const urlText, 00339 MemoryManager* const manager) : 00340 00341 fMemoryManager(manager) 00342 , fFragment(0) 00343 , fHost(0) 00344 , fPassword(0) 00345 , fPath(0) 00346 , fPortNum(0) 00347 , fProtocol(XMLURL::Unknown) 00348 , fQuery(0) 00349 , fUser(0) 00350 , fURLText(0) 00351 , fHasInvalidChar(false) 00352 { 00353 CleanupType cleanup(this, &XMLURL::cleanUp); 00354 00355 XMLCh* tmpText = XMLString::transcode(urlText, fMemoryManager); 00356 ArrayJanitor<XMLCh> janRel(tmpText, fMemoryManager); 00357 try 00358 { 00359 setURL(tmpText); 00360 } 00361 catch(const OutOfMemoryException&) 00362 { 00363 cleanup.release(); 00364 00365 throw; 00366 } 00367 00368 cleanup.release(); 00369 } 00370 00371 XMLURL::XMLURL(const XMLURL& toCopy) : 00372 XMemory(toCopy) 00373 , fMemoryManager(toCopy.fMemoryManager) 00374 , fFragment(0) 00375 , fHost(0) 00376 , fPassword(0) 00377 , fPath(0) 00378 , fPortNum(toCopy.fPortNum) 00379 , fProtocol(toCopy.fProtocol) 00380 , fQuery(0) 00381 , fUser(0) 00382 , fURLText(0) 00383 , fHasInvalidChar(toCopy.fHasInvalidChar) 00384 { 00385 CleanupType cleanup(this, &XMLURL::cleanUp); 00386 00387 try 00388 { 00389 fFragment = XMLString::replicate(toCopy.fFragment, fMemoryManager); 00390 fHost = XMLString::replicate(toCopy.fHost, fMemoryManager); 00391 fPassword = XMLString::replicate(toCopy.fPassword, fMemoryManager); 00392 fPath = XMLString::replicate(toCopy.fPath, fMemoryManager); 00393 fQuery = XMLString::replicate(toCopy.fQuery, fMemoryManager); 00394 fUser = XMLString::replicate(toCopy.fUser, fMemoryManager); 00395 fURLText = XMLString::replicate(toCopy.fURLText, fMemoryManager); 00396 } 00397 catch(const OutOfMemoryException&) 00398 { 00399 cleanup.release(); 00400 00401 throw; 00402 } 00403 00404 cleanup.release(); 00405 } 00406 00407 XMLURL::~XMLURL() 00408 { 00409 cleanUp(); 00410 } 00411 00412 00413 // --------------------------------------------------------------------------- 00414 // XMLURL: Public operators 00415 // --------------------------------------------------------------------------- 00416 XMLURL& XMLURL::operator=(const XMLURL& toAssign) 00417 { 00418 if (this == &toAssign) 00419 return *this; 00420 00421 // Clean up our stuff 00422 cleanUp(); 00423 00424 // And copy his stuff 00425 fMemoryManager = toAssign.fMemoryManager; 00426 fFragment = XMLString::replicate(toAssign.fFragment, fMemoryManager); 00427 fHost = XMLString::replicate(toAssign.fHost, fMemoryManager); 00428 fPassword = XMLString::replicate(toAssign.fPassword, fMemoryManager); 00429 fPath = XMLString::replicate(toAssign.fPath, fMemoryManager); 00430 fPortNum = toAssign.fPortNum; 00431 fProtocol = toAssign.fProtocol; 00432 fQuery = XMLString::replicate(toAssign.fQuery, fMemoryManager); 00433 fUser = XMLString::replicate(toAssign.fUser, fMemoryManager); 00434 fURLText = XMLString::replicate(toAssign.fURLText, fMemoryManager); 00435 fHasInvalidChar = toAssign.fHasInvalidChar; 00436 00437 return *this; 00438 } 00439 00440 bool XMLURL::operator==(const XMLURL& toCompare) const 00441 { 00442 // 00443 // Compare the two complete URLs (which have been processed the same 00444 // way so they should now be the same even if they came in via different 00445 // relative parts. 00446 // 00447 if (!XMLString::equals(getURLText(), toCompare.getURLText())) 00448 return false; 00449 00450 return true; 00451 } 00452 00453 00454 00455 // --------------------------------------------------------------------------- 00456 // XMLURL: Getter methods 00457 // --------------------------------------------------------------------------- 00458 unsigned int XMLURL::getPortNum() const 00459 { 00460 // 00461 // If it was not provided explicitly, then lets return the default one 00462 // for the protocol. 00463 // 00464 if (!fPortNum) 00465 { 00466 if (fProtocol == Unknown) 00467 return 0; 00468 return gProtoList[fProtocol].defPort; 00469 } 00470 return fPortNum; 00471 } 00472 00473 00474 const XMLCh* XMLURL::getProtocolName() const 00475 { 00476 // Check to see if its ever been set 00477 if (fProtocol == Unknown) 00478 ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_NoProtocolPresent, fMemoryManager); 00479 00480 return gProtoList[fProtocol].prefix; 00481 } 00482 00483 00484 // --------------------------------------------------------------------------- 00485 // XMLURL: Setter methods 00486 // --------------------------------------------------------------------------- 00487 void XMLURL::setURL(const XMLCh* const urlText) 00488 { 00489 // 00490 // Try to parse the URL. 00491 // 00492 cleanUp(); 00493 parse(urlText); 00494 } 00495 00496 void XMLURL::setURL(const XMLCh* const baseURL 00497 , const XMLCh* const relativeURL) 00498 { 00499 cleanUp(); 00500 00501 // Parse our URL string 00502 parse(relativeURL); 00503 00504 // 00505 // If its relative and the base is non-null and non-empty, then 00506 // parse the base URL string and conglomerate them. 00507 // 00508 if (isRelative() && baseURL) 00509 { 00510 if (*baseURL) 00511 { 00512 XMLURL basePart(baseURL, fMemoryManager); 00513 if (!conglomerateWithBase(basePart, false)) 00514 { 00515 cleanUp(); 00516 ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_RelativeBaseURL, fMemoryManager); 00517 } 00518 } 00519 } 00520 } 00521 00522 // this version of setURL doesn't throw a malformedurl exception 00523 // instead it returns false when it failed (or when it would of 00524 // thrown a malformedurl exception) 00525 bool XMLURL::setURL(const XMLCh* const baseURL 00526 , const XMLCh* const relativeURL 00527 , XMLURL& xmlURL) 00528 { 00529 cleanUp(); 00530 00531 // Parse our URL string 00532 if (parse(relativeURL, xmlURL)) 00533 { 00534 // If its relative and the base is non-null and non-empty, then 00535 // parse the base URL string and conglomerate them. 00536 // 00537 if (isRelative() && baseURL && *baseURL) 00538 { 00539 XMLURL basePart(fMemoryManager); 00540 if (parse(baseURL, basePart) && conglomerateWithBase(basePart, false)) 00541 { 00542 return true; 00543 } 00544 } 00545 else 00546 return true; 00547 } 00548 return false; 00549 } 00550 00551 void XMLURL::setURL(const XMLURL& baseURL 00552 , const XMLCh* const relativeURL) 00553 { 00554 cleanUp(); 00555 00556 // Parse our URL string 00557 parse(relativeURL); 00558 00559 // If its relative, then conglomerate with the base URL 00560 if (isRelative()) 00561 conglomerateWithBase(baseURL); 00562 } 00563 00564 00565 // --------------------------------------------------------------------------- 00566 // XMLURL: Miscellaneous methods 00567 // --------------------------------------------------------------------------- 00568 bool XMLURL::isRelative() const 00569 { 00570 // If no protocol then relative 00571 if (fProtocol == Unknown) 00572 return true; 00573 00574 // If no path, or the path is not absolute, then relative 00575 if (!fPath) 00576 return true; 00577 00578 if (*fPath != chForwardSlash) 00579 return true; 00580 00581 return false; 00582 } 00583 00584 00585 bool XMLURL::hasInvalidChar() const { 00586 return fHasInvalidChar; 00587 } 00588 00589 00590 BinInputStream* XMLURL::makeNewStream() const 00591 { 00592 // 00593 // If its a local host, then we short circuit it and use our own file 00594 // stream support. Otherwise, we just let it fall through and let the 00595 // installed network access object provide a stream. 00596 // 00597 if (fProtocol == XMLURL::File) 00598 { 00599 if (!fHost || !XMLString::compareIStringASCII(fHost, XMLUni::fgLocalHostString)) 00600 { 00601 00602 XMLCh* realPath = XMLString::replicate(fPath, fMemoryManager); 00603 ArrayJanitor<XMLCh> basePathName(realPath, fMemoryManager); 00604 00605 // 00606 // Need to manually replace any character reference %xx first 00607 // HTTP protocol will be done automatically by the netaccessor 00608 // 00609 XMLSize_t end = XMLString::stringLen(realPath); 00610 int percentIndex = XMLString::indexOf(realPath, chPercent, 0, fMemoryManager); 00611 00612 while (percentIndex != -1) { 00613 00614 if (percentIndex+2 >= (int)end || 00615 !isHexDigit(realPath[percentIndex+1]) || 00616 !isHexDigit(realPath[percentIndex+2])) 00617 { 00618 XMLCh value1[4]; 00619 XMLString::moveChars(value1, &(realPath[percentIndex]), 3); 00620 value1[3] = chNull; 00621 ThrowXMLwithMemMgr2(MalformedURLException 00622 , XMLExcepts::XMLNUM_URI_Component_Invalid_EscapeSequence 00623 , realPath 00624 , value1 00625 , fMemoryManager); 00626 } 00627 00628 unsigned int value = (xlatHexDigit(realPath[percentIndex+1]) * 16) + xlatHexDigit(realPath[percentIndex+2]); 00629 00630 realPath[percentIndex] = XMLCh(value); 00631 00632 XMLSize_t i =0; 00633 for (i = percentIndex + 1; i < end - 2 ; i++) 00634 realPath[i] = realPath[i+2]; 00635 realPath[i] = chNull; 00636 end = i; 00637 00638 if (((XMLSize_t)(percentIndex + 1)) < end) 00639 percentIndex = XMLString::indexOf(realPath, chPercent, percentIndex + 1, fMemoryManager); 00640 else 00641 percentIndex = -1; 00642 } 00643 00644 00645 BinFileInputStream* retStrm = new (fMemoryManager) BinFileInputStream(realPath, fMemoryManager); 00646 if (!retStrm->getIsOpen()) 00647 { 00648 delete retStrm; 00649 return 0; 00650 } 00651 return retStrm; 00652 } 00653 } 00654 00655 // 00656 // If we don't have have an installed net accessor object, then we 00657 // have to just throw here. 00658 // 00659 if (!XMLPlatformUtils::fgNetAccessor) 00660 ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_UnsupportedProto, fMemoryManager); 00661 00662 // Else ask the net accessor to create the stream 00663 return XMLPlatformUtils::fgNetAccessor->makeNew(*this); 00664 } 00665 00666 void XMLURL::makeRelativeTo(const XMLCh* const baseURLText) 00667 { 00668 // If this one is not relative, don't bother 00669 if (!isRelative()) 00670 return; 00671 00672 XMLURL baseURL(baseURLText, fMemoryManager); 00673 conglomerateWithBase(baseURL); 00674 } 00675 00676 void XMLURL::makeRelativeTo(const XMLURL& baseURL) 00677 { 00678 // If this one is not relative, don't bother 00679 if (!isRelative()) 00680 return; 00681 conglomerateWithBase(baseURL); 00682 } 00683 00684 00685 00686 00687 // --------------------------------------------------------------------------- 00688 // XMLURL: Private helper methods 00689 // --------------------------------------------------------------------------- 00690 00691 // 00692 // This method will take the broken out parts of the URL and build up the 00693 // full text. We don't do this unless someone asks us to, since its often 00694 // never required. 00695 // 00696 void XMLURL::buildFullText() 00697 { 00698 // Calculate the worst case size of the buffer required 00699 XMLSize_t bufSize = gMaxProtoLen + 1 00700 + XMLString::stringLen(fFragment) + 1 00701 + XMLString::stringLen(fHost) + 2 00702 + XMLString::stringLen(fPassword) + 1 00703 + XMLString::stringLen(fPath) 00704 + XMLString::stringLen(fQuery) + 1 00705 + XMLString::stringLen(fUser) + 1 00706 + 32; 00707 00708 // Clean up the existing buffer and allocate another 00709 fMemoryManager->deallocate(fURLText);//delete [] fURLText; 00710 fURLText = (XMLCh*) fMemoryManager->allocate((bufSize) * sizeof(XMLCh));//new XMLCh[bufSize]; 00711 *fURLText = 0; 00712 00713 XMLCh* outPtr = fURLText; 00714 if (fProtocol != Unknown) 00715 { 00716 XMLString::catString(fURLText, getProtocolName()); 00717 outPtr += XMLString::stringLen(fURLText); 00718 *outPtr++ = chColon; 00719 *outPtr++ = chForwardSlash; 00720 *outPtr++ = chForwardSlash; 00721 } 00722 00723 if (fUser) 00724 { 00725 XMLString::copyString(outPtr, fUser); 00726 outPtr += XMLString::stringLen(fUser); 00727 00728 if (fPassword) 00729 { 00730 *outPtr++ = chColon; 00731 XMLString::copyString(outPtr, fPassword); 00732 outPtr += XMLString::stringLen(fPassword); 00733 } 00734 00735 *outPtr++ = chAt; 00736 } 00737 00738 if (fHost) 00739 { 00740 XMLString::copyString(outPtr, fHost); 00741 outPtr += XMLString::stringLen(fHost); 00742 00743 // 00744 // If the port is zero, then we don't put it in. Else we need 00745 // to because it was explicitly provided. 00746 // 00747 if (fPortNum) 00748 { 00749 *outPtr++ = chColon; 00750 00751 XMLCh tmpBuf[17]; 00752 XMLString::binToText(fPortNum, tmpBuf, 16, 10, fMemoryManager); 00753 XMLString::copyString(outPtr, tmpBuf); 00754 outPtr += XMLString::stringLen(tmpBuf); 00755 } 00756 } 00757 00758 if (fPath) 00759 { 00760 XMLString::copyString(outPtr, fPath); 00761 outPtr += XMLString::stringLen(fPath); 00762 } 00763 00764 if (fQuery) 00765 { 00766 *outPtr++ = chQuestion; 00767 XMLString::copyString(outPtr, fQuery); 00768 outPtr += XMLString::stringLen(fQuery); 00769 } 00770 00771 if (fFragment) 00772 { 00773 *outPtr++ = chPound; 00774 XMLString::copyString(outPtr, fFragment); 00775 outPtr += XMLString::stringLen(fFragment); 00776 } 00777 00778 // Cap it off in case the last op was not a string copy 00779 *outPtr = 0; 00780 } 00781 00782 00783 // 00784 // Just a central place to handle cleanup, since its done from a number 00785 // of different spots. 00786 // 00787 void XMLURL::cleanUp() 00788 { 00789 fMemoryManager->deallocate(fFragment);//delete [] fFragment; 00790 fMemoryManager->deallocate(fHost);//delete [] fHost; 00791 fMemoryManager->deallocate(fPassword);//delete [] fPassword; 00792 fMemoryManager->deallocate(fPath);//delete [] fPath; 00793 fMemoryManager->deallocate(fQuery);//delete [] fQuery; 00794 fMemoryManager->deallocate(fUser);//delete [] fUser; 00795 fMemoryManager->deallocate(fURLText);//delete [] fURLText; 00796 00797 fFragment = 0; 00798 fHost = 0; 00799 fPassword = 0; 00800 fPath = 0; 00801 fQuery = 0; 00802 fUser = 0; 00803 fURLText = 0; 00804 00805 fProtocol = Unknown; 00806 fPortNum = 0; 00807 fHasInvalidChar = false; 00808 } 00809 00810 00811 //This function has been modified to take a bool parameter and the 00812 //functionality inside looks irrational but is only to make 00813 //solaris 2.7 CC 5.0 optimized build happy. 00814 00815 bool XMLURL::conglomerateWithBase(const XMLURL& baseURL, bool useExceptions) 00816 { 00817 // The base URL cannot be relative 00818 if (baseURL.isRelative()) 00819 { 00820 if (useExceptions) 00821 ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_RelativeBaseURL, fMemoryManager); 00822 else 00823 return false; 00824 } 00825 00826 // 00827 // Check a special case. If all we have is a fragment, then we want 00828 // to just take the base host and path, plus our fragment. 00829 // 00830 if ((fProtocol == Unknown) 00831 && !fHost 00832 && !fPath 00833 && fFragment) 00834 { 00835 // Just in case, make sure we don't leak the user or password values 00836 fMemoryManager->deallocate(fUser);//delete [] fUser; 00837 fUser = 0; 00838 fMemoryManager->deallocate(fPassword);//delete [] fPassword; 00839 fPassword = 0; 00840 00841 // Copy over the protocol and port number as is 00842 fProtocol = baseURL.fProtocol; 00843 fPortNum = baseURL.fPortNum; 00844 00845 // Replicate the base fields that are provided 00846 fHost = XMLString::replicate(baseURL.fHost, fMemoryManager); 00847 fUser = XMLString::replicate(baseURL.fUser, fMemoryManager); 00848 fPassword = XMLString::replicate(baseURL.fPassword, fMemoryManager); 00849 fPath = XMLString::replicate(baseURL.fPath, fMemoryManager); 00850 return true; 00851 } 00852 00853 // 00854 // All we have to do is run up through our fields and, for each one 00855 // that we don't have, use the based URL's. Once we hit one field 00856 // that we have, we stop. 00857 // 00858 if (fProtocol != Unknown) 00859 return true; 00860 fProtocol = baseURL.fProtocol; 00861 00862 // 00863 // If the protocol is not file, and we either already have our own 00864 // host, or the base does not have one, then we are done. 00865 // 00866 if (fProtocol != File) 00867 { 00868 if (fHost || !baseURL.fHost) 00869 return true; 00870 } 00871 00872 // Replicate all of the hosty stuff if the base has one 00873 if (baseURL.fHost) 00874 { 00875 // Just in case, make sure we don't leak a user or password field 00876 fMemoryManager->deallocate(fUser);//delete [] fUser; 00877 fUser = 0; 00878 fMemoryManager->deallocate(fPassword);//delete [] fPassword; 00879 fPassword = 0; 00880 fMemoryManager->deallocate(fHost);//delete [] fHost; 00881 fHost = 0; 00882 00883 fHost = XMLString::replicate(baseURL.fHost, fMemoryManager); 00884 fUser = XMLString::replicate(baseURL.fUser, fMemoryManager); 00885 fPassword = XMLString::replicate(baseURL.fPassword, fMemoryManager); 00886 00887 fPortNum = baseURL.fPortNum; 00888 } 00889 00890 // If we have a path and its absolute, then we are done 00891 const bool hadPath = (fPath != 0); 00892 if (hadPath) 00893 { 00894 if (*fPath == chForwardSlash) 00895 return true; 00896 } 00897 00898 // Its a relative path, so weave them together. 00899 if (baseURL.fPath) { 00900 XMLCh* temp = XMLPlatformUtils::weavePaths(baseURL.fPath, fPath ,fMemoryManager); 00901 fMemoryManager->deallocate(fPath);//delete [] fPath; 00902 fPath = temp; 00903 } 00904 00905 // If we had any original path, then we are done 00906 if (hadPath) 00907 return true; 00908 00909 // We had no original path, so go on to deal with the query/fragment parts 00910 if (fQuery || !baseURL.fQuery) 00911 return true; 00912 fQuery = XMLString::replicate(baseURL.fQuery, fMemoryManager); 00913 00914 if (fFragment || !baseURL.fFragment) 00915 return true; 00916 fFragment = XMLString::replicate(baseURL.fFragment, fMemoryManager); 00917 return true; 00918 } 00919 00920 00921 void XMLURL::parse(const XMLCh* const urlText) 00922 { 00923 // Simplify things by checking for the psycho scenarios first 00924 if (!*urlText) 00925 ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_NoProtocolPresent, fMemoryManager); 00926 00927 // Before we start, check if this urlText contains valid uri characters 00928 if (!XMLUri::isURIString(urlText)) 00929 fHasInvalidChar = true; 00930 else 00931 fHasInvalidChar = false; 00932 00933 // 00934 // The first thing we will do is to check for a file name, so that 00935 // we don't waste time thinking its a URL. If its in the form x:\ or x:/ 00936 // and x is an ASCII letter, then assume that's the deal. 00937 // 00938 if (((*urlText >= chLatin_A) && (*urlText <= chLatin_Z)) 00939 || ((*urlText >= chLatin_a) && (*urlText <= chLatin_z))) 00940 { 00941 if (*(urlText + 1) == chColon) 00942 { 00943 if ((*(urlText + 2) == chForwardSlash) 00944 || (*(urlText + 2) == chBackSlash)) 00945 { 00946 ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_NoProtocolPresent, fMemoryManager); 00947 } 00948 } 00949 } 00950 00951 // Get a copy of the URL that we can modify 00952 XMLCh* srcCpy = XMLString::replicate(urlText, fMemoryManager); 00953 ArrayJanitor<XMLCh> janSrcCopy(srcCpy, fMemoryManager); 00954 00955 // 00956 // Get a pointer now that we can run up thrown the source as we parse 00957 // bits and pieces out of it. 00958 // 00959 XMLCh* srcPtr = srcCpy; 00960 00961 // Run up past any spaces 00962 while (*srcPtr) 00963 { 00964 if (!XMLChar1_0::isWhitespace(*srcPtr)) 00965 break; 00966 srcPtr++; 00967 } 00968 00969 // Make sure it wasn't all space 00970 if (!*srcPtr) 00971 ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_NoProtocolPresent, fMemoryManager); 00972 00973 // 00974 // Ok, the next thing we have to do is to find either a / or : character. 00975 // If the : is first, we assume we have a protocol. If the / is first, 00976 // then we skip to the host processing. 00977 // 00978 XMLCh* ptr1 = XMLString::findAny(srcPtr, gListOne); 00979 XMLCh* ptr2; 00980 00981 // If we found a protocol, then deal with it 00982 if (ptr1) 00983 { 00984 if (*ptr1 == chColon) 00985 { 00986 // Cap the string at the colon 00987 *ptr1 = 0; 00988 00989 // And try to find it in our list of protocols 00990 fProtocol = lookupByName(srcPtr); 00991 00992 if (fProtocol == Unknown) 00993 { 00994 ThrowXMLwithMemMgr1 00995 ( 00996 MalformedURLException 00997 , XMLExcepts::URL_UnsupportedProto1 00998 , srcPtr 00999 , fMemoryManager 01000 ); 01001 } 01002 01003 // And move our source pointer up past what we've processed 01004 srcPtr = (ptr1 + 1); 01005 } 01006 } 01007 01008 // 01009 // Ok, next we need to see if we have any host part. If the next 01010 // two characters are //, then we need to check, else move on. 01011 // 01012 if ((*srcPtr == chForwardSlash) && (*(srcPtr + 1) == chForwardSlash)) 01013 { 01014 // Move up past the slashes 01015 srcPtr += 2; 01016 01017 // 01018 // If we aren't at the end of the string, then there has to be a 01019 // host part at this point. we will just look for the next / char 01020 // or end of string and make all of that the host for now. 01021 // 01022 if (*srcPtr) 01023 { 01024 // Search from here for a / character 01025 ptr1 = XMLString::findAny(srcPtr, gListFour); 01026 01027 // 01028 // If we found something, then the host is between where 01029 // we are and what we found. Else the host is the rest of 01030 // the content and we are done. If its empty, leave it null. 01031 // 01032 if (ptr1) 01033 { 01034 if (ptr1 != srcPtr) 01035 { 01036 fMemoryManager->deallocate(fHost);//delete [] fHost; 01037 fHost = (XMLCh*) fMemoryManager->allocate 01038 ( 01039 ((ptr1 - srcPtr) + 1) * sizeof(XMLCh) 01040 );//new XMLCh[(ptr1 - srcPtr) + 1]; 01041 ptr2 = fHost; 01042 while (srcPtr < ptr1) 01043 *ptr2++ = *srcPtr++; 01044 *ptr2 = 0; 01045 } 01046 } 01047 else 01048 { 01049 fMemoryManager->deallocate(fHost);//delete [] fHost; 01050 fHost = XMLString::replicate(srcPtr, fMemoryManager); 01051 01052 // Update source pointer to the end 01053 srcPtr += XMLString::stringLen(fHost); 01054 } 01055 } 01056 } 01057 else 01058 { 01059 // 01060 // http protocol requires two forward slashes 01061 // we didn't get them, so throw an exception 01062 // 01063 if (fProtocol == HTTP) { 01064 ThrowXMLwithMemMgr 01065 ( 01066 MalformedURLException 01067 , XMLExcepts::URL_ExpectingTwoSlashes 01068 , fMemoryManager 01069 ); 01070 } 01071 } 01072 01073 // 01074 // If there was a host part, then we have to grovel through it for 01075 // all the bits and pieces it can hold. 01076 // 01077 if (fHost) 01078 { 01079 // 01080 // Look for a '@' character, which indicates a user name. If we 01081 // find one, then everything between the start of the host data 01082 // and the character is the user name. 01083 // 01084 ptr1 = XMLString::findAny(fHost, gListTwo); 01085 if (ptr1) 01086 { 01087 // Get this info out as the user name 01088 *ptr1 = 0; 01089 fMemoryManager->deallocate(fUser);//delete [] fUser; 01090 fUser = XMLString::replicate(fHost, fMemoryManager); 01091 ptr1++; 01092 01093 // And now cut these chars from the host string 01094 XMLString::cut(fHost, ptr1 - fHost); 01095 01096 // Is there a password inside the user string? 01097 ptr2 = XMLString::findAny(fUser, gListThree); 01098 if (ptr2) 01099 { 01100 // Remove it from the user name string 01101 *ptr2 = 0; 01102 01103 // And copy out the remainder to the password field 01104 ptr2++; 01105 fMemoryManager->deallocate(fPassword);//delete [] fPassword; 01106 fPassword = XMLString::replicate(ptr2, fMemoryManager); 01107 } 01108 } 01109 01110 // 01111 // Ok, so now we are at the actual host name, if any. If we are 01112 // not at the end of the host data, then lets see if we have a 01113 // port trailing the 01114 // 01115 ptr1 = XMLString::findAny(fHost, gListThree); 01116 if (ptr1) 01117 { 01118 // Remove it from the host name 01119 *ptr1 = 0; 01120 01121 // Try to convert it to a numeric port value and store it 01122 ptr1++; 01123 if (!XMLString::textToBin(ptr1, fPortNum, fMemoryManager)) 01124 ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_BadPortField, fMemoryManager); 01125 } 01126 01127 // If the host ended up empty, then toss is 01128 if (!*fHost) 01129 { 01130 fMemoryManager->deallocate(fHost);//delete[] fHost; 01131 fHost = 0; 01132 } 01133 } 01134 01135 // If we are at the end, then we are done now 01136 if (!*srcPtr) { 01137 if(fHost) { 01138 static const XMLCh slash[] = { chForwardSlash, chNull }; 01139 fPath = XMLString::replicate(slash, fMemoryManager); 01140 } 01141 return; 01142 } 01143 01144 // 01145 // Next is the path part. It can be absolute, i.e. starting with a 01146 // forward slash character, or relative. Its basically everything up 01147 // to the end of the string or to any trailing query or fragment. 01148 // 01149 ptr1 = XMLString::findAny(srcPtr, gListFive); 01150 if (!ptr1) 01151 { 01152 fMemoryManager->deallocate(fPath);//delete [] fPath; 01153 fPath = XMLString::replicate(srcPtr, fMemoryManager); 01154 return; 01155 } 01156 01157 // Everything from where we are to what we found is the path 01158 if (ptr1 > srcPtr) 01159 { 01160 fMemoryManager->deallocate(fPath);//delete [] fPath; 01161 fPath = (XMLCh*) fMemoryManager->allocate 01162 ( 01163 ((ptr1 - srcPtr) + 1) * sizeof(XMLCh) 01164 );//new XMLCh[(ptr1 - srcPtr) + 1]; 01165 ptr2 = fPath; 01166 while (srcPtr < ptr1) 01167 *ptr2++ = *srcPtr++; 01168 *ptr2 = 0; 01169 } 01170 01171 // 01172 // If we found a fragment, then it is the rest of the string and we 01173 // are done. 01174 // 01175 if (*srcPtr == chPound) 01176 { 01177 srcPtr++; 01178 fMemoryManager->deallocate(fFragment);//delete [] fFragment; 01179 fFragment = XMLString::replicate(srcPtr, fMemoryManager); 01180 return; 01181 } 01182 01183 // 01184 // The query is either the rest of the string, or up to the fragment 01185 // separator. 01186 // 01187 srcPtr++; 01188 ptr1 = XMLString::findAny(srcPtr, gListSix); 01189 fMemoryManager->deallocate(fQuery);//delete [] fQuery; 01190 if (!ptr1) 01191 { 01192 fQuery = XMLString::replicate(srcPtr, fMemoryManager); 01193 return; 01194 } 01195 else 01196 { 01197 fQuery = (XMLCh*) fMemoryManager->allocate 01198 ( 01199 ((ptr1 - srcPtr) + 1) * sizeof(XMLCh) 01200 );//new XMLCh[(ptr1 - srcPtr) + 1]; 01201 ptr2 = fQuery; 01202 while (srcPtr < ptr1) 01203 *ptr2++ = *srcPtr++; 01204 *ptr2 = 0; 01205 } 01206 01207 // If we are not at the end now, then everything else is the fragment 01208 if (*srcPtr == chPound) 01209 { 01210 srcPtr++; 01211 fMemoryManager->deallocate(fFragment);//delete [] fFragment; 01212 fFragment = XMLString::replicate(srcPtr, fMemoryManager); 01213 } 01214 } 01215 01216 bool XMLURL::parse(const XMLCh* const urlText, XMLURL& xmlURL) 01217 { 01218 // Simplify things by checking for the psycho scenarios first 01219 if (!*urlText) 01220 return false; 01221 01222 // Before we start, check if this urlText contains valid uri characters 01223 if (!XMLUri::isURIString(urlText)) 01224 xmlURL.fHasInvalidChar = true; 01225 else 01226 xmlURL.fHasInvalidChar = false; 01227 01228 // 01229 // The first thing we will do is to check for a file name, so that 01230 // we don't waste time thinking its a URL. If its in the form x:\ or x:/ 01231 // and x is an ASCII letter, then assume that's the deal. 01232 // 01233 if (((*urlText >= chLatin_A) && (*urlText <= chLatin_Z)) 01234 || ((*urlText >= chLatin_a) && (*urlText <= chLatin_z))) 01235 { 01236 if (*(urlText + 1) == chColon) 01237 { 01238 if ((*(urlText + 2) == chForwardSlash) 01239 || (*(urlText + 2) == chBackSlash)) 01240 { 01241 return false; 01242 } 01243 } 01244 } 01245 01246 // Get a copy of the URL that we can modify 01247 XMLCh* srcCpy = XMLString::replicate(urlText, xmlURL.fMemoryManager); 01248 ArrayJanitor<XMLCh> janSrcCopy(srcCpy, xmlURL.fMemoryManager); 01249 01250 // 01251 // Get a pointer now that we can run up thrown the source as we parse 01252 // bits and pieces out of it. 01253 // 01254 XMLCh* srcPtr = srcCpy; 01255 01256 // Run up past any spaces 01257 while (*srcPtr) 01258 { 01259 if (!XMLChar1_0::isWhitespace(*srcPtr)) 01260 break; 01261 srcPtr++; 01262 } 01263 01264 // Make sure it wasn't all space 01265 if (!*srcPtr) 01266 return false; 01267 01268 // 01269 // Ok, the next thing we have to do is to find either a / or : character. 01270 // If the : is first, we assume we have a protocol. If the / is first, 01271 // then we skip to the host processing. 01272 // 01273 XMLCh* ptr1 = XMLString::findAny(srcPtr, gListOne); 01274 XMLCh* ptr2; 01275 01276 // If we found a protocol, then deal with it 01277 if (ptr1) 01278 { 01279 if (*ptr1 == chColon) 01280 { 01281 // Cap the string at the colon 01282 *ptr1 = 0; 01283 01284 // And try to find it in our list of protocols 01285 xmlURL.fProtocol = lookupByName(srcPtr); 01286 01287 if (xmlURL.fProtocol == Unknown) 01288 return false; 01289 01290 // And move our source pointer up past what we've processed 01291 srcPtr = (ptr1 + 1); 01292 } 01293 } 01294 01295 // 01296 // Ok, next we need to see if we have any host part. If the next 01297 // two characters are //, then we need to check, else move on. 01298 // 01299 if ((*srcPtr == chForwardSlash) && (*(srcPtr + 1) == chForwardSlash)) 01300 { 01301 // Move up past the slashes 01302 srcPtr += 2; 01303 01304 // 01305 // If we aren't at the end of the string, then there has to be a 01306 // host part at this point. we will just look for the next / char 01307 // or end of string and make all of that the host for now. 01308 // 01309 if (*srcPtr) 01310 { 01311 // Search from here for a / character 01312 ptr1 = XMLString::findAny(srcPtr, gListFour); 01313 01314 // 01315 // If we found something, then the host is between where 01316 // we are and what we found. Else the host is the rest of 01317 // the content and we are done. If its empty, leave it null. 01318 // 01319 if (ptr1) 01320 { 01321 if (ptr1 != srcPtr) 01322 { 01323 xmlURL.fHost = (XMLCh*) xmlURL.fMemoryManager->allocate 01324 ( 01325 ((ptr1 - srcPtr) + 1) * sizeof(XMLCh) 01326 );//new XMLCh[(ptr1 - srcPtr) + 1]; 01327 ptr2 = xmlURL.fHost; 01328 while (srcPtr < ptr1) 01329 *ptr2++ = *srcPtr++; 01330 *ptr2 = 0; 01331 } 01332 } 01333 else 01334 { 01335 xmlURL.fHost = XMLString::replicate(srcPtr, xmlURL.fMemoryManager); 01336 01337 // Update source pointer to the end 01338 srcPtr += XMLString::stringLen(xmlURL.fHost); 01339 } 01340 } 01341 } 01342 else 01343 { 01344 // 01345 // http protocol requires two forward slashes 01346 // we didn't get them, so throw an exception 01347 // 01348 if (xmlURL.fProtocol == HTTP) 01349 return false; 01350 } 01351 01352 // 01353 // If there was a host part, then we have to grovel through it for 01354 // all the bits and pieces it can hold. 01355 // 01356 if (xmlURL.fHost) 01357 { 01358 // 01359 // Look for a '@' character, which indicates a user name. If we 01360 // find one, then everything between the start of the host data 01361 // and the character is the user name. 01362 // 01363 ptr1 = XMLString::findAny(xmlURL.fHost, gListTwo); 01364 if (ptr1) 01365 { 01366 // Get this info out as the user name 01367 *ptr1 = 0; 01368 xmlURL.fUser = XMLString::replicate(xmlURL.fHost, xmlURL.fMemoryManager); 01369 ptr1++; 01370 01371 // And now cut these chars from the host string 01372 XMLString::cut(xmlURL.fHost, ptr1 - xmlURL.fHost); 01373 01374 // Is there a password inside the user string? 01375 ptr2 = XMLString::findAny(xmlURL.fUser, gListThree); 01376 if (ptr2) 01377 { 01378 // Remove it from the user name string 01379 *ptr2 = 0; 01380 01381 // And copy out the remainder to the password field 01382 ptr2++; 01383 xmlURL.fPassword = XMLString::replicate(ptr2, xmlURL.fMemoryManager); 01384 } 01385 } 01386 01387 // 01388 // Ok, so now we are at the actual host name, if any. If we are 01389 // not at the end of the host data, then lets see if we have a 01390 // port trailing the 01391 // 01392 ptr1 = XMLString::findAny(xmlURL.fHost, gListThree); 01393 if (ptr1) 01394 { 01395 // Remove it from the host name 01396 *ptr1 = 0; 01397 01398 // Try to convert it to a numeric port value and store it 01399 ptr1++; 01400 if (!XMLString::textToBin(ptr1, xmlURL.fPortNum, xmlURL.fMemoryManager)) 01401 return false; 01402 } 01403 01404 // If the host ended up empty, then toss is 01405 if (!*(xmlURL.fHost)) 01406 { 01407 xmlURL.fMemoryManager->deallocate(xmlURL.fHost);//delete[] fHost; 01408 xmlURL.fHost = 0; 01409 } 01410 } 01411 01412 // If we are at the end, then we are done now 01413 if (!*srcPtr) { 01414 if(xmlURL.fHost) { 01415 static const XMLCh slash[] = { chForwardSlash, chNull }; 01416 xmlURL.fPath = XMLString::replicate(slash, xmlURL.fMemoryManager); 01417 } 01418 return true; 01419 } 01420 01421 // 01422 // Next is the path part. It can be absolute, i.e. starting with a 01423 // forward slash character, or relative. Its basically everything up 01424 // to the end of the string or to any trailing query or fragment. 01425 // 01426 ptr1 = XMLString::findAny(srcPtr, gListFive); 01427 if (!ptr1) 01428 { 01429 xmlURL.fPath = XMLString::replicate(srcPtr, xmlURL.fMemoryManager); 01430 return true; 01431 } 01432 01433 // Everything from where we are to what we found is the path 01434 if (ptr1 > srcPtr) 01435 { 01436 xmlURL.fPath = (XMLCh*) xmlURL.fMemoryManager->allocate 01437 ( 01438 ((ptr1 - srcPtr) + 1) * sizeof(XMLCh) 01439 );//new XMLCh[(ptr1 - srcPtr) + 1]; 01440 ptr2 = xmlURL.fPath; 01441 while (srcPtr < ptr1) 01442 *ptr2++ = *srcPtr++; 01443 *ptr2 = 0; 01444 } 01445 01446 // 01447 // If we found a fragment, then it is the rest of the string and we 01448 // are done. 01449 // 01450 if (*srcPtr == chPound) 01451 { 01452 srcPtr++; 01453 xmlURL.fFragment = XMLString::replicate(srcPtr, xmlURL.fMemoryManager); 01454 return true; 01455 } 01456 01457 // 01458 // The query is either the rest of the string, or up to the fragment 01459 // separator. 01460 // 01461 srcPtr++; 01462 ptr1 = XMLString::findAny(srcPtr, gListSix); 01463 if (!ptr1) 01464 { 01465 xmlURL.fQuery = XMLString::replicate(srcPtr, xmlURL.fMemoryManager); 01466 return true; 01467 } 01468 else 01469 { 01470 xmlURL.fQuery = (XMLCh*) xmlURL.fMemoryManager->allocate 01471 ( 01472 ((ptr1 - srcPtr) + 1) * sizeof(XMLCh) 01473 );//new XMLCh[(ptr1 - srcPtr) + 1]; 01474 ptr2 = xmlURL.fQuery; 01475 while (srcPtr < ptr1) 01476 *ptr2++ = *srcPtr++; 01477 *ptr2 = 0; 01478 } 01479 01480 // If we are not at the end now, then everything else is the fragment 01481 if (*srcPtr == chPound) 01482 { 01483 srcPtr++; 01484 xmlURL.fFragment = XMLString::replicate(srcPtr, xmlURL.fMemoryManager); 01485 } 01486 01487 return true; 01488 } 01489 01490 XERCES_CPP_NAMESPACE_END