You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
akode/akode/lib/mmapfile.cpp

151 lines
3.3 KiB

/* 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;
}
ssize_t MMapFile::lseek(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 length();
}
if (newpos > len || newpos < 0)
return -1;
pos = newpos;
return newpos;
}
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