This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
/*****************************************************************************
|
||||
|
||||
$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
|
||||
Reference in New Issue
Block a user