GME  13
XIncludeLocation.cpp
Go to the documentation of this file.
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: XIncludeLocation.cpp 932949 2010-04-11 17:40:33Z borisk $
00020  */
00021 
00022 
00023 // ---------------------------------------------------------------------------
00024 //  Includes
00025 // ---------------------------------------------------------------------------
00026 #include <xercesc/xinclude/XIncludeLocation.hpp>
00027 #include <xercesc/dom/DOM.hpp>
00028 #include <xercesc/util/XMLUniDefs.hpp>
00029 
00030 XERCES_CPP_NAMESPACE_BEGIN
00031 
00032 const XMLCh *allocate(const XMLCh *href){
00033     XMLCh *allocated;
00034     XMLSize_t length = XMLString::stringLen(href);
00035     allocated = (XMLCh*)XMLPlatformUtils::fgMemoryManager->allocate((length+1) * sizeof(XMLCh));
00036     XMLString::copyString(allocated, href);
00037     XMLPlatformUtils::removeDotDotSlash(allocated);
00038 
00039     return allocated;
00040 }
00041 
00042 void deallocate(void *ptr){
00043     if (ptr)
00044         XMLPlatformUtils::fgMemoryManager->deallocate((void *)ptr);
00045 }
00046 
00047 // ---------------------------------------------------------------------------
00048 //  Destructor and Constructor
00049 // ---------------------------------------------------------------------------
00050 XIncludeLocation::XIncludeLocation(const XMLCh *href){
00051     fHref = allocate(href);
00052 }
00053 
00054 XIncludeLocation::~XIncludeLocation(){
00055     deallocate((void *)fHref);
00056 }
00057 
00058 const XMLCh *
00059 XIncludeLocation::prependPath(const XMLCh *baseToAdd){
00060     XMLCh *relativeHref = NULL;
00061     if (fHref == NULL){
00062         return NULL;
00063     }
00064 
00065     if (baseToAdd == NULL){
00066         return fHref;
00067     }
00068 
00069     XMLPlatformUtils::removeDotDotSlash((XMLCh*)baseToAdd);
00070     XMLSize_t baseLength = XMLString::stringLen(baseToAdd);
00071 
00072     int lastSlash = XMLString::lastIndexOf(baseToAdd, chForwardSlash);
00073     if (lastSlash == -1){
00074         /* not found, try another platform */
00075         lastSlash = XMLString::lastIndexOf(baseToAdd, chBackSlash);
00076     }
00077 
00078     // Skip the scheme (e.g., file://) if fHref has one. Ideally we
00079     // should detect also if the URI is absolute.
00080     //
00081     const XMLCh* hrefPath = findEndOfProtocol (fHref);
00082     XMLSize_t hrefPathLength = XMLString::stringLen(hrefPath);
00083 
00084     relativeHref = (XMLCh *)XMLPlatformUtils::fgMemoryManager->allocate((hrefPathLength + baseLength + 2) * sizeof(XMLCh));
00085     if (relativeHref == NULL){
00086         return NULL;
00087     }
00088     XMLString::copyNString(relativeHref, baseToAdd, lastSlash + 1);
00089     relativeHref[lastSlash + 1] = chNull;
00090     XMLString::catString(relativeHref, hrefPath);
00091 
00092     /* free the old reference */
00093     deallocate((void *)fHref);
00094 
00095     fHref = relativeHref;
00096     return fHref;
00097 }
00098 
00099 const XMLCh *
00100 XIncludeLocation::findEndOfProtocol(const XMLCh *URI){
00101     if ( URI[0] == chLatin_f &&
00102         URI[1] == chLatin_i &&
00103         URI[2] == chLatin_l &&
00104         URI[3] == chLatin_e &&
00105         URI[4] == chColon &&
00106         URI[5] == chForwardSlash &&
00107         URI[6] == chForwardSlash &&
00108         URI[7] == chForwardSlash )
00109     {
00110         return URI + 8;
00111     }
00112 
00113     if ( URI[0] == chLatin_f &&
00114         URI[1] == chLatin_t &&
00115         URI[2] == chLatin_p &&
00116         URI[3] == chColon &&
00117         URI[4] == chForwardSlash &&
00118         URI[5] == chForwardSlash &&
00119         URI[6] == chForwardSlash )
00120     {
00121         return URI + 7;
00122     }
00123 
00124     if ( URI[0] == chLatin_h &&
00125         URI[1] == chLatin_t &&
00126         URI[2] == chLatin_t &&
00127         URI[3] == chLatin_p &&
00128         URI[4] == chColon &&
00129         URI[5] == chForwardSlash &&
00130         URI[6] == chForwardSlash &&
00131         URI[7] == chForwardSlash )
00132     {
00133         return URI + 8;
00134     }
00135 
00136     /* if method fails, simply return the URI and let the problem be detected
00137      * and reported down the line (it may not have a protocol of course) */
00138     return URI;
00139 }
00140 
00141 XERCES_CPP_NAMESPACE_END