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 + -
显示快捷键?