File: MappedFile.cc

package info (click to toggle)
fastdep 0.16-7
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 596 kB
  • ctags: 323
  • sloc: cpp: 2,144; ansic: 814; sh: 208; makefile: 124
file content (144 lines) | stat: -rw-r--r-- 2,916 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#ifdef WIN32

#include <direct.h>
#include <io.h>
#define PATH_MAX MAX_PATH
#else
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>

#endif

#include <memory>

#include "MappedFile.h"

#ifdef WIN32
//http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/pal/filetime_8c-source.html
static const __int64 SECS_BETWEEN_EPOCHS = 11644473600;
static const __int64 SECS_TO_100NS = 10000000; /* 10^7 */
 

time_t FILEFileTimeToUnixTime( FILETIME FileTime, long *nsec )
{
     __int64 UnixTime;
 
     /* get the full win32 value, in 100ns */
    UnixTime = ((__int64)FileTime.dwHighDateTime << 32) + 
         FileTime.dwLowDateTime;
 
     /* convert to the Unix epoch */
     UnixTime -= (SECS_BETWEEN_EPOCHS * SECS_TO_100NS);
 
//     TRACE("nsec=%p\n", nsec);
 
     if ( nsec )
     {
         /* get the number of 100ns, convert to ns */
         *nsec = (UnixTime % SECS_TO_100NS) * 100;
     }
 
     UnixTime /= SECS_TO_100NS; /* now convert to seconds */
 
     if ( (time_t)UnixTime != UnixTime )
     {
//         WARN("Resulting value is too big for a time_t value\n");
     }
 
     /*
	 TRACE("Win32 FILETIME = [%#x:%#x] converts to Unix time = [%ld.%09ld]\n", 
           FileTime.dwHighDateTime, FileTime.dwLowDateTime ,(long) UnixTime,
           nsec?*nsec:0L);
 */
     return (time_t)UnixTime;
 }

MappedFile::~MappedFile()
{
	UnmapViewOfFile(map_);
	CloseHandle(hFileMapping);
	CloseHandle(hFile);		
}

bool MappedFile::open(const std::string& name)
{
	hFile = CreateFile(name.c_str(), 
			GENERIC_READ, 
			FILE_SHARE_READ, 
			NULL, 
			OPEN_EXISTING, 
			FILE_ATTRIBUTE_NORMAL, 
			NULL);
	opened_ = hFile == INVALID_HANDLE_VALUE ? false : true ; 

	if (opened_)
	{
		file_size = GetFileSize(hFile, NULL);
		FILETIME fTime;
		GetFileTime(hFile, NULL, NULL,&fTime);
		long nsec;
		last_change = FILEFileTimeToUnixTime( fTime, &nsec );
	}
	return opened_;
}

char* MappedFile::map() throw (std::string)
{	
	hFileMapping = CreateFileMapping(
					hFile,NULL,
					PAGE_WRITECOPY, 0, 0, NULL
					);
	return map_=(char*)MapViewOfFile(hFileMapping, FILE_MAP_COPY, 0, 0, 0);
};

#else
		
MappedFile::~MappedFile()
{
	if(opened_)
	{
		munmap(map_, mapsize);
		close(fd);
	}
}

				
bool MappedFile::open(const std::string& name)
{
	fd = ::open(name.c_str(), O_RDONLY);
	opened_ = fd >= 0 ? true : false ;
	if(opened_)
	{
		struct stat st;
		fstat(fd, &st);
		file_size = st.st_size;
		last_change = st.st_mtime;
		mapsize = st.st_size;
	}
	return opened_;
}

char* MappedFile::map() throw (std::string)
{
	int pagesizem1 = getpagesize()-1;

	mapsize = (mapsize+pagesizem1) & ~pagesizem1;
	map_ = (char*)mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
	if ((long) map_ == -1) 
	{
		perror("mkdep: mmap");
		close(fd);
		return 0;
	}
	if ((unsigned long) map_ % sizeof(unsigned long) != 0)
	{
		throw std::string("do_depend: map not aligned") ;
	}	
	return map_;
};

#endif

// vim:ts=4:nu
//