GME  13
PosixFileMgr.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: PosixFileMgr.cpp 673975 2008-07-04 09:23:56Z borisk $
00020  */
00021 
00022 #include <stdio.h>
00023 #include <unistd.h>
00024 #include <limits.h>
00025 
00026 #include <xercesc/util/FileManagers/PosixFileMgr.hpp>
00027 
00028 #include <xercesc/util/PlatformUtils.hpp>
00029 #include <xercesc/util/Janitor.hpp>
00030 #include <xercesc/util/RuntimeException.hpp>
00031 #include <xercesc/util/PanicHandler.hpp>
00032 #include <xercesc/util/XMLString.hpp>
00033 
00034 
00035 XERCES_CPP_NAMESPACE_BEGIN
00036 
00037 
00038 PosixFileMgr::PosixFileMgr()
00039 {
00040 }
00041 
00042 
00043 PosixFileMgr::~PosixFileMgr()
00044 {
00045 }
00046 
00047 
00048 FileHandle
00049 PosixFileMgr::fileOpen(const XMLCh* path, bool toWrite, MemoryManager* const manager)
00050 {
00051     const char* tmpFileName = XMLString::transcode(path, manager);
00052     ArrayJanitor<char> janText((char*)tmpFileName, manager);
00053     return fileOpen(tmpFileName, toWrite, manager);
00054 }
00055 
00056 
00057 FileHandle
00058 PosixFileMgr::fileOpen(const char* path, bool toWrite, MemoryManager* const /*manager*/)
00059 {
00060     const char* perms = (toWrite) ? "wb" : "rb";
00061     FileHandle result = (FileHandle)fopen(path , perms);
00062     return result;
00063 }
00064 
00065 
00066 FileHandle
00067 PosixFileMgr::openStdIn(MemoryManager* const /*manager*/)
00068 {
00069     return (FileHandle)fdopen(dup(0), "rb");
00070 }
00071 
00072 
00073 void
00074 PosixFileMgr::fileClose(FileHandle f, MemoryManager* const manager)
00075 {
00076     if (!f)
00077                 ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero, manager);
00078 
00079     if (fclose((FILE*)f))
00080         ThrowXMLwithMemMgr(XMLPlatformUtilsException,
00081                  XMLExcepts::File_CouldNotCloseFile, manager);
00082 }
00083 
00084 
00085 void
00086 PosixFileMgr::fileReset(FileHandle f, MemoryManager* const manager)
00087 {
00088     if (!f)
00089                 ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero, manager);
00090 
00091     // Seek to the start of the file
00092     if (fseek((FILE*)f, 0, SEEK_SET))
00093         ThrowXMLwithMemMgr(XMLPlatformUtilsException,
00094                  XMLExcepts::File_CouldNotResetFile, manager);
00095 }
00096 
00097 
00098 XMLFilePos
00099 PosixFileMgr::curPos(FileHandle f, MemoryManager* const manager)
00100 {
00101     if (!f)
00102                 ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero, manager);
00103                  
00104     long curPos = ftell((FILE*)f);
00105         
00106     if (curPos == -1)
00107         ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetSize, manager);
00108 
00109     return (XMLFilePos)curPos;
00110 }
00111 
00112 
00113 XMLFilePos
00114 PosixFileMgr::fileSize(FileHandle f, MemoryManager* const manager)
00115 {
00116     if (!f)
00117                 ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero, manager);
00118                 
00119     // Get the current position
00120     long curPos = ftell((FILE*)f);
00121     if (curPos == -1)
00122         ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos, manager);
00123 
00124     // Seek to the end and save that value for return
00125     if (fseek((FILE*)f, 0, SEEK_END))
00126         ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd, manager);
00127 
00128     long retVal = ftell((FILE*)f);
00129     if (retVal == -1)
00130         ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd, manager);
00131 
00132     // And put the pointer back
00133     if (fseek((FILE*)f, curPos, SEEK_SET))
00134         ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToPos, manager);
00135 
00136     return (XMLFilePos)retVal;
00137 }
00138 
00139 
00140 XMLSize_t
00141 PosixFileMgr::fileRead(FileHandle f, XMLSize_t byteCount, XMLByte* buffer, MemoryManager* const manager)
00142 {
00143     if (!f || !buffer)
00144                 ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero, manager);
00145                 
00146     XMLSize_t bytesRead = 0;
00147         if (byteCount > 0)
00148         {
00149         bytesRead = fread((void*)buffer, 1, byteCount, (FILE*)f);
00150 
00151                 if (ferror((FILE*)f))
00152                         ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile, manager);
00153         }
00154         
00155     return bytesRead;
00156 }
00157 
00158 
00159 void
00160 PosixFileMgr::fileWrite(FileHandle f, XMLSize_t byteCount, const XMLByte* buffer, MemoryManager* const manager)
00161 {
00162     if (!f || !buffer)
00163                 ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero, manager);
00164 
00165     while (byteCount > 0)
00166     {
00167         XMLSize_t bytesWritten = fwrite(buffer, sizeof(XMLByte), byteCount, (FILE*)f);
00168 
00169         if (ferror((FILE*)f))
00170                         ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile, manager);
00171 
00172                 buffer          += bytesWritten;
00173                 byteCount       -= bytesWritten;
00174     }
00175 }
00176 
00177 
00178 XMLCh*
00179 PosixFileMgr::getFullPath(const XMLCh* const srcPath, MemoryManager* const manager)
00180 {
00181     //
00182     //  NOTE: The path provided has always already been opened successfully,
00183     //  so we know that its not some pathological freaky path. It comes in
00184     //  in native format, and goes out as Unicode always
00185     //
00186     char* newSrc = XMLString::transcode(srcPath, manager);
00187     ArrayJanitor<char> janText(newSrc, manager);
00188 
00189     // Use a local buffer that is big enough for the largest legal path
00190     char absPath[PATH_MAX + 1];
00191     
00192     // get the absolute path
00193     if (!realpath(newSrc, absPath))
00194                 ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetBasePathName, manager);
00195 
00196     return XMLString::transcode(absPath, manager);
00197 }
00198 
00199 
00200 XMLCh*
00201 PosixFileMgr::getCurrentDirectory(MemoryManager* const manager)
00202 {
00203     char dirBuf[PATH_MAX + 2];
00204     char *curDir = getcwd(&dirBuf[0], PATH_MAX + 1);
00205 
00206     if (!curDir)
00207         ThrowXMLwithMemMgr(XMLPlatformUtilsException,
00208                  XMLExcepts::File_CouldNotGetBasePathName, manager);
00209 
00210     return XMLString::transcode(curDir, manager);
00211 }
00212 
00213 
00214 bool
00215 PosixFileMgr::isRelative(const XMLCh* const toCheck, MemoryManager* const /*manager*/)
00216 {
00217     // Check for pathological case of empty path
00218     if (!toCheck || !toCheck[0])
00219         return false;
00220 
00221     //
00222     //  If it starts with a slash, then it cannot be relative.
00223     //
00224     return toCheck[0] != XMLCh('/');
00225 }
00226 
00227 
00228 XERCES_CPP_NAMESPACE_END
00229