-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathgrfcache.h
122 lines (112 loc) · 2.43 KB
/
grfcache.h
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
#ifndef GRFCACHE_H
#define GRFCACHE_H
#include <windows.h>
#include <libgrf/grf.h>
#include <string>
#include <hash_map>
class GrfCache
{
private:
struct FileMappingInfo
{
HANDLE hFile;
HANDLE hFileMapping;
};
typedef stdext::hash_map< std::string, Grf* > GrfEnsemble;
typedef stdext::hash_map< std::string, FileMappingInfo > MappingsEnsemble;
public:
GrfCache() {}
~GrfCache() throw()
{
empty_all();
}
Grf *get(const std::string& name) throw(int, GrfError)
{
Grf *pGrf;
GrfError errorcode;
if ( m.find(name) != m.end() )
{
return m[name];
}
try
{
pGrf = grf_open(name.c_str(), "rb", &errorcode);
}
catch(...)
{
throw 0;
}
if ( pGrf == 0 )
{
throw errorcode;
}
m[name] = pGrf;
return pGrf;
}
HANDLE getFileMapping(const std::string& name)
{
FileMappingInfo mappingInfo;
if ( m_FileMappings.find(name) != m_FileMappings.end() )
{
return m_FileMappings[name].hFileMapping;
}
mappingInfo.hFile = ::CreateFile(name.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if ( mappingInfo.hFile == INVALID_HANDLE_VALUE )
{
return 0;
}
DWORD dwFileSize = ::GetFileSize(mappingInfo.hFile, NULL);
if ( dwFileSize == 0 )
{
::CloseHandle(mappingInfo.hFile);
return 0;
}
// NULL ACL token
mappingInfo.hFileMapping = ::CreateFileMapping(mappingInfo.hFile, NULL, PAGE_READONLY, 0, dwFileSize, NULL /*name*/);
if ( !mappingInfo.hFileMapping )
{
::CloseHandle(mappingInfo.hFile);
return 0;
}
m_FileMappings[name] = mappingInfo;
return mappingInfo.hFileMapping;
}
HANDLE getFileFromMapping(HANDLE hMapping)
{
for ( MappingsEnsemble::iterator it = m_FileMappings.begin(); it != m_FileMappings.end(); ++it )
{
FileMappingInfo &mappingInfo = it->second;
if ( mappingInfo.hFileMapping == hMapping )
{
return (mappingInfo.hFile);
}
}
}
void empty_all()
{
for ( GrfEnsemble::iterator it = m.begin(); it != m.end(); ++it )
{
try
{
grf_free(it->second);
}
catch(...)
{}
}
m.clear();
for ( MappingsEnsemble::iterator it = m_FileMappings.begin(); it != m_FileMappings.end(); ++it )
{
FileMappingInfo &mappingInfo = it->second;
::CloseHandle(mappingInfo.hFileMapping);
::CloseHandle(mappingInfo.hFile);
}
m_FileMappings.clear();
}
private:
GrfEnsemble m;
MappingsEnsemble m_FileMappings;
private:
GrfCache(const GrfCache&) {}
GrfCache& operator=(const GrfCache&) {}
};
#endif