diff options
Diffstat (limited to 'akode/lib/mmapfile.cpp')
-rw-r--r-- | akode/lib/mmapfile.cpp | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/akode/lib/mmapfile.cpp b/akode/lib/mmapfile.cpp new file mode 100644 index 0000000..4c45603 --- /dev/null +++ b/akode/lib/mmapfile.cpp @@ -0,0 +1,150 @@ +/* aKode: MMapFile + + Copyright (C) 2004 Allan Sandfeld Jensen <kde@carewolf.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "akodelib.h" + +extern "C" { + #ifdef HAVE_FEATURES_H + // Needed for older glibc versions. + #include <features.h> + #ifndef __USE_XOPEN2K + #define __USE_XOPEN2K + #endif + #endif + + #include <unistd.h> + #ifdef HAVE_SYS_TYPES_H + #include <sys/types.h> + #endif + #include <sys/mman.h> + #include <sys/stat.h> + #include <fcntl.h> + #include <string.h> + + #if defined(HAVE_MADVISE) && defined(NEED_MADVISE_PROTOTYPE) + extern int madvise(void*,size_t,int); + #endif +} + +#include "mmapfile.h" + +namespace aKode { + +MMapFile::MMapFile(const char* filename) : File(filename), fd(-1), handle(0), len(0), pos(0) {} + +MMapFile::~MMapFile() { + close(); +} + +bool MMapFile::openRO() { + if(handle) return true; + struct stat stat; + + fd = ::open(filename, O_RDONLY); + if (fstat(fd, &stat) < 0) return false; + len = stat.st_size; + pos = 0; + + handle = mmap(0, len, PROT_READ, MAP_SHARED, fd, 0); + if (handle == MAP_FAILED) { + ::close(fd); + handle = 0; + return false; + } + + return true; +} + +void MMapFile::close() { + if(handle) { + munmap((char*)handle,len); + ::close(fd); + } + handle = 0; +} + +long MMapFile::read(char* ptr, long num) { + if(!handle) return -1; + + if (pos+num > len) num = len-pos; + memcpy(ptr, (char*)handle+pos, num); + pos += num; + + return num; +} + +long MMapFile::write(const char*, long) { + return false; +} + +bool MMapFile::seek(long to, int whence) { + if(!handle) return false; + + long newpos = 0; + switch (whence) { + case SEEK_SET: + newpos = to; + break; + case SEEK_CUR: + newpos = pos + to; + break; + case SEEK_END: + newpos = len + to; + break; + default: + return false; + } + if (newpos > len || newpos < 0) + return false; + pos = newpos; + return true; +} + +long MMapFile::position() const { + if(!handle) return -1; + + return pos; +} + +long MMapFile::length() const { + if(!handle) return -1; + + return len; +} + +bool MMapFile::error() const { + return (!handle); +} + +bool MMapFile::eof() const { + if(!handle) return true; + return pos >= len; +} + +void MMapFile::fadvise() { + if(!handle) return; + #if defined(HAVE_POSIX_MADVISE) && defined(POSIX_MADV_SEQUENTIAL) + posix_madvise((char*)handle+pos, len-pos, POSIX_MADV_SEQUENTIAL); + #elif defined(HAVE_MADVISE) && defined(MADV_SEQUENTIAL) + madvise((char*)handle+pos, len-pos, MADV_SEQUENTIAL); + #endif +} + +} //namespace |