| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| // --------------------------------------------------------------------------- |
| // Includes |
| // --------------------------------------------------------------------------- |
| #include <xercesc/framework/LocalFileInputSource.hpp> |
| #include <xercesc/util/BinFileInputStream.hpp> |
| #include <xercesc/util/PlatformUtils.hpp> |
| #include <xercesc/util/XMLString.hpp> |
| #include <xercesc/util/XMLUniDefs.hpp> |
| |
| XERCES_CPP_NAMESPACE_BEGIN |
| |
| /*** |
| * |
| * Originated by Chris larsson |
| * |
| * Issue: |
| * |
| * There is an inconsistency in URI resolution in the case where the file itself is a |
| * symbolic link to another path (or the path has path segment which is a symbolic |
| * link to another path). So, is the base path the directory where the symbolic link resides |
| * or the directory where the real file resides? I'm sure one could argue either way, |
| * but I think that having the base path be the directory where the symbolic link resides |
| * is more intuitive. |
| * |
| * Defining it this way would then make the behavior consistent with using an absolute |
| * path as well as with the java behavior. |
| * |
| * Proposal: |
| * |
| * The URI is resolved within the parser code, and is somewhat independant of the OS. |
| * |
| * A relative path is resolved by querying the current directory and appending the |
| * relative part onto the returned current directory string to obtain the base URI. |
| * An absolute path is simply used as the base URI. |
| * Then remove all "./" and "../" path segments using an algorithm like weavepath to obtain |
| * the resolved base URI. |
| * |
| * When you need to access another file such as a dtd, use the resolved base URI and add on |
| * the relative URI of the dtd file. Then resolve it using the same weavepath algorithm. |
| * |
| * Note: |
| * |
| * Java parser behaves differently for a path containning symbolic path segment. When |
| * it is given an absolute path, it can locate the primary instance document, while given |
| * relative path, it might not. |
| * |
| * It is because Java parser uses URI solution where "/segment/../" is required to be removed |
| * from the resultant path if a relative URI is merged to a baseURI. While this is NOT required |
| * for an absolute URI. |
| * |
| * So if a path segment, which is symbolic link, happen to be followed by the '/../', it is |
| * NOT removed from the path if it is given in absolute form, and the underlying file system |
| * will locate the file, if in relative form, that symbolic link path segment together with |
| * '../' is removed from the resultant path, and the file system may NOT be able to locate |
| * the file, if there is a one, it is definitely not the one expected, in fact by accident. |
| * |
| * Therefore, to keep consistent with Java parser, for now, we do not apply removeDotDotSlash() |
| * for absolute path. |
| * |
| ***/ |
| |
| // --------------------------------------------------------------------------- |
| // LocalFileInputSource: Constructors and Destructor |
| // --------------------------------------------------------------------------- |
| LocalFileInputSource::LocalFileInputSource( const XMLCh* const basePath |
| , const XMLCh* const relativePath |
| , MemoryManager* const manager) |
| : InputSource(manager) |
| { |
| // |
| // If the relative part is really relative, then weave it together |
| // with the base path. If not, just take the relative path as the |
| // entire path. |
| // |
| if (XMLPlatformUtils::isRelative(relativePath, manager)) |
| { |
| XMLCh* tmpBuf = XMLPlatformUtils::weavePaths(basePath, relativePath, manager); |
| setSystemId(tmpBuf); |
| manager->deallocate(tmpBuf); //delete [] tmpBuf; |
| } |
| else |
| { |
| XMLCh* tmpBuf = XMLString::replicate(relativePath, manager); |
| XMLPlatformUtils::removeDotSlash(tmpBuf, manager); |
| setSystemId(tmpBuf); |
| manager->deallocate(tmpBuf);//delete [] tmpBuf; |
| } |
| |
| } |
| |
| LocalFileInputSource::LocalFileInputSource(const XMLCh* const filePath, |
| MemoryManager* const manager) |
| : InputSource(manager) |
| { |
| |
| // |
| // If the path is relative, then complete it acording to the current |
| // working directory rules of the current platform. Else, just take |
| // it as is. |
| // |
| if (XMLPlatformUtils::isRelative(filePath, manager)) |
| { |
| XMLCh* curDir = XMLPlatformUtils::getCurrentDirectory(manager); |
| |
| int curDirLen = XMLString::stringLen(curDir); |
| int filePathLen = XMLString::stringLen(filePath); |
| XMLCh* fullDir = (XMLCh*) manager->allocate |
| ( |
| (curDirLen + filePathLen + 2) * sizeof(XMLCh) |
| );//new XMLCh [ curDirLen + filePathLen + 2]; |
| |
| XMLString::copyString(fullDir, curDir); |
| fullDir[curDirLen] = chForwardSlash; |
| XMLString::copyString(&fullDir[curDirLen+1], filePath); |
| |
| XMLPlatformUtils::removeDotSlash(fullDir, manager); |
| XMLPlatformUtils::removeDotDotSlash(fullDir, manager); |
| |
| setSystemId(fullDir); |
| |
| manager->deallocate(curDir);//delete [] curDir; |
| manager->deallocate(fullDir);//delete [] fullDir; |
| } |
| else |
| { |
| XMLCh* tmpBuf = XMLString::replicate(filePath, manager); |
| XMLPlatformUtils::removeDotSlash(tmpBuf, manager); |
| setSystemId(tmpBuf); |
| manager->deallocate(tmpBuf);//delete [] tmpBuf; |
| } |
| |
| } |
| |
| LocalFileInputSource::~LocalFileInputSource() |
| { |
| } |
| |
| |
| // --------------------------------------------------------------------------- |
| // LocalFileInputSource: InputSource interface implementation |
| // --------------------------------------------------------------------------- |
| BinInputStream* LocalFileInputSource::makeStream() const |
| { |
| BinFileInputStream* retStrm = new (getMemoryManager()) BinFileInputStream(getSystemId(), getMemoryManager()); |
| if (!retStrm->getIsOpen()) |
| { |
| delete retStrm; |
| return 0; |
| } |
| return retStrm; |
| } |
| |
| XERCES_CPP_NAMESPACE_END |
| |