215 lines
4.4 KiB
C++
215 lines
4.4 KiB
C++
/*****************************************************************************
|
|
|
|
$Id: mapper.cpp 4527 2007-07-04 10:21:34Z francis $
|
|
|
|
File: mapper.cpp
|
|
Date: 02Jul07
|
|
|
|
Copyright (C) 2007 by Francis Cianfrocca. All Rights Reserved.
|
|
Gmail: garbagecat10
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of either: 1) the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version; or 2) Ruby's License.
|
|
|
|
See the file COPYING for complete licensing information.
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// UNIX implementation
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#ifdef OS_UNIX
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/mman.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <cstring>
|
|
#include <stdexcept>
|
|
|
|
#include "mapper.h"
|
|
|
|
/******************
|
|
Mapper_t::Mapper_t
|
|
******************/
|
|
|
|
Mapper_t::Mapper_t (const std::string &filename)
|
|
{
|
|
/* We ASSUME we can open the file.
|
|
* (More precisely, we assume someone else checked before we got here.)
|
|
*/
|
|
|
|
Fd = open (filename.c_str(), O_RDONLY);
|
|
if (Fd < 0)
|
|
throw std::runtime_error (strerror (errno));
|
|
|
|
struct stat st;
|
|
if (fstat (Fd, &st))
|
|
throw std::runtime_error (strerror (errno));
|
|
FileSize = st.st_size;
|
|
|
|
#ifdef OS_WIN32
|
|
MapPoint = (char*) mmap (0, FileSize, PROT_READ, MAP_SHARED, Fd, 0);
|
|
#else
|
|
MapPoint = (const char*) mmap (0, FileSize, PROT_READ, MAP_SHARED, Fd, 0);
|
|
#endif
|
|
if (MapPoint == MAP_FAILED)
|
|
throw std::runtime_error (strerror (errno));
|
|
}
|
|
|
|
|
|
/*******************
|
|
Mapper_t::~Mapper_t
|
|
*******************/
|
|
|
|
Mapper_t::~Mapper_t()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
|
|
/***************
|
|
Mapper_t::Close
|
|
***************/
|
|
|
|
void Mapper_t::Close()
|
|
{
|
|
// Can be called multiple times.
|
|
// Calls to GetChunk are invalid after a call to Close.
|
|
if (MapPoint) {
|
|
#ifdef CC_SUNWspro
|
|
// TODO: The void * cast works fine on Solaris 11, but
|
|
// I don't know at what point that changed from older Solaris.
|
|
munmap ((char*)MapPoint, FileSize);
|
|
#else
|
|
munmap ((void*)MapPoint, FileSize);
|
|
#endif
|
|
MapPoint = NULL;
|
|
}
|
|
if (Fd >= 0) {
|
|
close (Fd);
|
|
Fd = -1;
|
|
}
|
|
}
|
|
|
|
/******************
|
|
Mapper_t::GetChunk
|
|
******************/
|
|
|
|
const char *Mapper_t::GetChunk (unsigned start)
|
|
{
|
|
return MapPoint + start;
|
|
}
|
|
|
|
|
|
|
|
#endif // OS_UNIX
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// WINDOWS implementation
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#ifdef OS_WIN32
|
|
|
|
#include <windows.h>
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <stdexcept>
|
|
|
|
#include "mapper.h"
|
|
|
|
/******************
|
|
Mapper_t::Mapper_t
|
|
******************/
|
|
|
|
Mapper_t::Mapper_t (const std::string &filename)
|
|
{
|
|
/* We ASSUME we can open the file.
|
|
* (More precisely, we assume someone else checked before we got here.)
|
|
*/
|
|
|
|
hFile = INVALID_HANDLE_VALUE;
|
|
hMapping = NULL;
|
|
MapPoint = NULL;
|
|
FileSize = 0;
|
|
|
|
hFile = CreateFile (filename.c_str(), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
throw std::runtime_error ("File not found");
|
|
|
|
BY_HANDLE_FILE_INFORMATION i;
|
|
if (GetFileInformationByHandle (hFile, &i))
|
|
FileSize = i.nFileSizeLow;
|
|
|
|
hMapping = CreateFileMapping (hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
|
|
if (!hMapping)
|
|
throw std::runtime_error ("File not mapped");
|
|
|
|
#ifdef OS_WIN32
|
|
MapPoint = (char*) MapViewOfFile (hMapping, FILE_MAP_WRITE, 0, 0, 0);
|
|
#else
|
|
MapPoint = (const char*) MapViewOfFile (hMapping, FILE_MAP_WRITE, 0, 0, 0);
|
|
#endif
|
|
if (!MapPoint)
|
|
throw std::runtime_error ("Mappoint not read");
|
|
}
|
|
|
|
|
|
/*******************
|
|
Mapper_t::~Mapper_t
|
|
*******************/
|
|
|
|
Mapper_t::~Mapper_t()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
/***************
|
|
Mapper_t::Close
|
|
***************/
|
|
|
|
void Mapper_t::Close()
|
|
{
|
|
// Can be called multiple times.
|
|
// Calls to GetChunk are invalid after a call to Close.
|
|
if (MapPoint) {
|
|
UnmapViewOfFile (MapPoint);
|
|
MapPoint = NULL;
|
|
}
|
|
if (hMapping != NULL) {
|
|
CloseHandle (hMapping);
|
|
hMapping = NULL;
|
|
}
|
|
if (hFile != INVALID_HANDLE_VALUE) {
|
|
CloseHandle (hFile);
|
|
hFile = INVALID_HANDLE_VALUE;
|
|
}
|
|
}
|
|
|
|
|
|
/******************
|
|
Mapper_t::GetChunk
|
|
******************/
|
|
|
|
const char *Mapper_t::GetChunk (unsigned start)
|
|
{
|
|
return MapPoint + start;
|
|
}
|
|
|
|
|
|
|
|
#endif // OS_WINDOWS
|