| /* |
| * 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. |
| */ |
| |
| /* |
| * $Id$ |
| */ |
| |
| #include <config.h> |
| #include <cstdio> |
| |
| #if HAVE_UNISTD_H |
| #include <unistd.h> |
| #endif |
| |
| #if HAVE_LIMITS_H |
| #include <limits.h> |
| #endif |
| |
| #include <xercesc/util/FileManagers/PosixFileMgr.hpp> |
| |
| #include <xercesc/util/PlatformUtils.hpp> |
| #include <xercesc/util/Janitor.hpp> |
| #include <xercesc/util/RuntimeException.hpp> |
| #include <xercesc/util/PanicHandler.hpp> |
| #include <xercesc/util/XMLString.hpp> |
| #include <xercesc/util/XMLUniDefs.hpp> |
| |
| |
| XERCES_CPP_NAMESPACE_BEGIN |
| |
| |
| PosixFileMgr::PosixFileMgr() |
| { |
| } |
| |
| |
| PosixFileMgr::~PosixFileMgr() |
| { |
| } |
| |
| |
| FileHandle |
| PosixFileMgr::fileOpen(const XMLCh* path, bool toWrite, MemoryManager* const manager) |
| { |
| const char* tmpFileName = XMLString::transcode(path, manager); |
| ArrayJanitor<char> janText((char*)tmpFileName, manager); |
| return fileOpen(tmpFileName, toWrite, manager); |
| } |
| |
| |
| FileHandle |
| PosixFileMgr::fileOpen(const char* path, bool toWrite, MemoryManager* const /*manager*/) |
| { |
| const char* perms = (toWrite) ? "wb" : "rb"; |
| FileHandle result = (FileHandle)fopen(path , perms); |
| return result; |
| } |
| |
| |
| FileHandle |
| PosixFileMgr::openStdIn(MemoryManager* const /*manager*/) |
| { |
| return (FileHandle)fdopen(dup(0), "rb"); |
| } |
| |
| |
| void |
| PosixFileMgr::fileClose(FileHandle f, MemoryManager* const manager) |
| { |
| if (!f) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero, manager); |
| |
| if (fclose((FILE*)f)) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, |
| XMLExcepts::File_CouldNotCloseFile, manager); |
| } |
| |
| |
| void |
| PosixFileMgr::fileReset(FileHandle f, MemoryManager* const manager) |
| { |
| if (!f) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero, manager); |
| |
| // Seek to the start of the file |
| if (fseek((FILE*)f, 0, SEEK_SET)) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, |
| XMLExcepts::File_CouldNotResetFile, manager); |
| } |
| |
| |
| XMLFilePos |
| PosixFileMgr::curPos(FileHandle f, MemoryManager* const manager) |
| { |
| if (!f) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero, manager); |
| |
| long curPos = ftell((FILE*)f); |
| |
| if (curPos == -1) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetSize, manager); |
| |
| return (XMLFilePos)curPos; |
| } |
| |
| |
| XMLFilePos |
| PosixFileMgr::fileSize(FileHandle f, MemoryManager* const manager) |
| { |
| if (!f) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero, manager); |
| |
| // Get the current position |
| long curPos = ftell((FILE*)f); |
| if (curPos == -1) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos, manager); |
| |
| // Seek to the end and save that value for return |
| if (fseek((FILE*)f, 0, SEEK_END)) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd, manager); |
| |
| long retVal = ftell((FILE*)f); |
| if (retVal == -1) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd, manager); |
| |
| // And put the pointer back |
| if (fseek((FILE*)f, curPos, SEEK_SET)) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToPos, manager); |
| |
| return (XMLFilePos)retVal; |
| } |
| |
| |
| XMLSize_t |
| PosixFileMgr::fileRead(FileHandle f, XMLSize_t byteCount, XMLByte* buffer, MemoryManager* const manager) |
| { |
| if (!f || !buffer) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero, manager); |
| |
| XMLSize_t bytesRead = 0; |
| if (byteCount > 0) |
| { |
| bytesRead = fread((void*)buffer, 1, byteCount, (FILE*)f); |
| |
| if (ferror((FILE*)f)) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile, manager); |
| } |
| |
| return bytesRead; |
| } |
| |
| |
| void |
| PosixFileMgr::fileWrite(FileHandle f, XMLSize_t byteCount, const XMLByte* buffer, MemoryManager* const manager) |
| { |
| if (!f || !buffer) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero, manager); |
| |
| while (byteCount > 0) |
| { |
| XMLSize_t bytesWritten = fwrite(buffer, sizeof(XMLByte), byteCount, (FILE*)f); |
| |
| if (ferror((FILE*)f)) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile, manager); |
| |
| buffer += bytesWritten; |
| byteCount -= bytesWritten; |
| } |
| } |
| |
| |
| XMLCh* |
| PosixFileMgr::getFullPath(const XMLCh* const srcPath, MemoryManager* const manager) |
| { |
| // |
| // NOTE: The path provided has always already been opened successfully, |
| // so we know that its not some pathological freaky path. It comes in |
| // in native format, and goes out as Unicode always |
| // |
| char* newSrc = XMLString::transcode(srcPath, manager); |
| ArrayJanitor<char> janText(newSrc, manager); |
| |
| #if HAVE_PATH_MAX |
| // Use a local buffer that is big enough for the largest legal path |
| char absPath[PATH_MAX + 1]; |
| |
| // get the absolute path |
| if (!realpath(newSrc, absPath)) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetBasePathName, manager); |
| |
| XMLCh* ret = XMLString::transcode(absPath, manager); |
| #else |
| // get the absolute path |
| char *absPath = realpath(newSrc, NULL); |
| if(!absPath) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetBasePathName, manager); |
| |
| XMLCh* ret = XMLString::transcode(absPath, manager); |
| free(absPath); |
| #endif |
| return ret; |
| } |
| |
| |
| XMLCh* |
| PosixFileMgr::getCurrentDirectory(MemoryManager* const manager) |
| { |
| #if HAVE_PATH_MAX |
| char dirBuf[PATH_MAX + 2]; |
| char *curDir = getcwd(&dirBuf[0], PATH_MAX + 1); |
| #else |
| char *curDir = getcwd(NULL, 0); |
| #endif |
| |
| if (!curDir) |
| ThrowXMLwithMemMgr(XMLPlatformUtilsException, |
| XMLExcepts::File_CouldNotGetBasePathName, manager); |
| |
| XMLCh* ret = XMLString::transcode(curDir, manager); |
| #if !HAVE_PATH_MAX |
| free(curDir); |
| #endif |
| return ret; |
| } |
| |
| |
| bool |
| PosixFileMgr::isRelative(const XMLCh* const toCheck, MemoryManager* const /*manager*/) |
| { |
| // Check for pathological case of empty path |
| if (!toCheck || !toCheck[0]) |
| return false; |
| |
| // |
| // If it starts with a slash, then it cannot be relative. |
| // |
| return toCheck[0] != chForwardSlash; |
| } |
| |
| |
| XERCES_CPP_NAMESPACE_END |
| |