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 // --------------------------------------------------------------------------- 00020 // Includes 00021 // --------------------------------------------------------------------------- 00022 #include <xercesc/framework/LocalFileInputSource.hpp> 00023 #include <xercesc/util/BinFileInputStream.hpp> 00024 #include <xercesc/util/PlatformUtils.hpp> 00025 #include <xercesc/util/XMLString.hpp> 00026 #include <xercesc/util/XMLUniDefs.hpp> 00027 00028 XERCES_CPP_NAMESPACE_BEGIN 00029 00030 /*** 00031 * 00032 * Originated by Chris larsson 00033 * 00034 * Issue: 00035 * 00036 * There is an inconsistency in URI resolution in the case where the file itself is a 00037 * symbolic link to another path (or the path has path segment which is a symbolic 00038 * link to another path). So, is the base path the directory where the symbolic link resides 00039 * or the directory where the real file resides? I'm sure one could argue either way, 00040 * but I think that having the base path be the directory where the symbolic link resides 00041 * is more intuitive. 00042 * 00043 * Defining it this way would then make the behavior consistent with using an absolute 00044 * path as well as with the java behavior. 00045 * 00046 * Proposal: 00047 * 00048 * The URI is resolved within the parser code, and is somewhat independant of the OS. 00049 * 00050 * A relative path is resolved by querying the current directory and appending the 00051 * relative part onto the returned current directory string to obtain the base URI. 00052 * An absolute path is simply used as the base URI. 00053 * Then remove all "./" and "../" path segments using an algorithm like weavepath to obtain 00054 * the resolved base URI. 00055 * 00056 * When you need to access another file such as a dtd, use the resolved base URI and add on 00057 * the relative URI of the dtd file. Then resolve it using the same weavepath algorithm. 00058 * 00059 * Note: 00060 * 00061 * Java parser behaves differently for a path containning symbolic path segment. When 00062 * it is given an absolute path, it can locate the primary instance document, while given 00063 * relative path, it might not. 00064 * 00065 * It is because Java parser uses URI solution where "/segment/../" is required to be removed 00066 * from the resultant path if a relative URI is merged to a baseURI. While this is NOT required 00067 * for an absolute URI. 00068 * 00069 * So if a path segment, which is symbolic link, happen to be followed by the '/../', it is 00070 * NOT removed from the path if it is given in absolute form, and the underlying file system 00071 * will locate the file, if in relative form, that symbolic link path segment together with 00072 * '../' is removed from the resultant path, and the file system may NOT be able to locate 00073 * the file, if there is a one, it is definitely not the one expected, in fact by accident. 00074 * 00075 * Therefore, to keep consistent with Java parser, for now, we do not apply removeDotDotSlash() 00076 * for absolute path. 00077 * 00078 ***/ 00079 00080 // --------------------------------------------------------------------------- 00081 // LocalFileInputSource: Constructors and Destructor 00082 // --------------------------------------------------------------------------- 00083 LocalFileInputSource::LocalFileInputSource( const XMLCh* const basePath 00084 , const XMLCh* const relativePath 00085 , MemoryManager* const manager) 00086 : InputSource(manager) 00087 { 00088 // 00089 // If the relative part is really relative, then weave it together 00090 // with the base path. If not, just take the relative path as the 00091 // entire path. 00092 // 00093 if (XMLPlatformUtils::isRelative(relativePath, manager)) 00094 { 00095 XMLCh* tmpBuf = XMLPlatformUtils::weavePaths(basePath, relativePath, manager); 00096 setSystemId(tmpBuf); 00097 manager->deallocate(tmpBuf); //delete [] tmpBuf; 00098 } 00099 else 00100 { 00101 XMLCh* tmpBuf = XMLString::replicate(relativePath, manager); 00102 XMLPlatformUtils::removeDotSlash(tmpBuf, manager); 00103 setSystemId(tmpBuf); 00104 manager->deallocate(tmpBuf);//delete [] tmpBuf; 00105 } 00106 00107 } 00108 00109 LocalFileInputSource::LocalFileInputSource(const XMLCh* const filePath, 00110 MemoryManager* const manager) 00111 : InputSource(manager) 00112 { 00113 00114 // 00115 // If the path is relative, then complete it acording to the current 00116 // working directory rules of the current platform. Else, just take 00117 // it as is. 00118 // 00119 if (XMLPlatformUtils::isRelative(filePath, manager)) 00120 { 00121 XMLCh* curDir = XMLPlatformUtils::getCurrentDirectory(manager); 00122 00123 XMLSize_t curDirLen = XMLString::stringLen(curDir); 00124 XMLSize_t filePathLen = XMLString::stringLen(filePath); 00125 XMLCh* fullDir = (XMLCh*) manager->allocate 00126 ( 00127 (curDirLen + filePathLen + 2) * sizeof(XMLCh) 00128 );//new XMLCh [ curDirLen + filePathLen + 2]; 00129 00130 XMLString::copyString(fullDir, curDir); 00131 fullDir[curDirLen] = chForwardSlash; 00132 XMLString::copyString(&fullDir[curDirLen+1], filePath); 00133 00134 XMLPlatformUtils::removeDotSlash(fullDir, manager); 00135 XMLPlatformUtils::removeDotDotSlash(fullDir, manager); 00136 00137 setSystemId(fullDir); 00138 00139 manager->deallocate(curDir);//delete [] curDir; 00140 manager->deallocate(fullDir);//delete [] fullDir; 00141 } 00142 else 00143 { 00144 XMLCh* tmpBuf = XMLString::replicate(filePath, manager); 00145 XMLPlatformUtils::removeDotSlash(tmpBuf, manager); 00146 setSystemId(tmpBuf); 00147 manager->deallocate(tmpBuf);//delete [] tmpBuf; 00148 } 00149 00150 } 00151 00152 LocalFileInputSource::~LocalFileInputSource() 00153 { 00154 } 00155 00156 00157 // --------------------------------------------------------------------------- 00158 // LocalFileInputSource: InputSource interface implementation 00159 // --------------------------------------------------------------------------- 00160 BinInputStream* LocalFileInputSource::makeStream() const 00161 { 00162 BinFileInputStream* retStrm = new (getMemoryManager()) BinFileInputStream(getSystemId(), getMemoryManager()); 00163 if (!retStrm->getIsOpen()) 00164 { 00165 delete retStrm; 00166 return 0; 00167 } 00168 return retStrm; 00169 } 00170 00171 XERCES_CPP_NAMESPACE_END 00172