Принемаются любые замечания в том числе к моему корявому английскому
//(C) Copyright WolfHound Softworks. All rights reserved.
//mail to wolfhound@mailru.com
#ifndef ___TSwap___H___
#define ___TSwap___H___
#include <windows.h>
template<class CData, int BlockSize=100> class TSwap
{
HANDLE file;
HANDLE mapping;
LPVOID map;
CData ErrAddr;
int PrivateDataCount;
DWORD FileSize;
public:
//Direct access declares
//WARNING: do not release this pointer
CData *Data;
int DataCount;
//Restore direct access variables
inline void Refresh()
{
DataCount=PrivateDataCount;
Data=(CData*)map;
}
//End of direct access declares
TSwap()
{
file=INVALID_HANDLE_VALUE;
mapping=NULL;
map=NULL;
PrivateDataCount=0;
DataCount=0;
Data=NULL;
}
~TSwap(){Close();}
//Release all resources
inline void Close()
{
if(NULL!=map)
{
UnmapViewOfFile(map);
map=NULL;
}
if(NULL!=mapping)
{
CloseHandle(mapping);
mapping=NULL;
}
if(INVALID_HANDLE_VALUE!=file)
{
CloseHandle(file);
file=INVALID_HANDLE_VALUE;
}
PrivateDataCount=0;
DataCount=0;
Data=NULL;
}
//Try to open old file map
inline bool Open(char *name)
{
Close();
file=CreateFile(
name,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(INVALID_HANDLE_VALUE==file) return false;
FileSize=GetFileSize(file, NULL);
if(0xFFFFFFFF==FileSize) return false;
if(FileSize%sizeof(CData)) return false;
mapping = CreateFileMapping(file, NULL, PAGE_READWRITE, 0, FileSize, NULL);
if(NULL==mapping) return false;
map = MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, FileSize);
if(NULL==map) return false;
DataCount=FileSize/sizeof(CData);
PrivateDataCount=DataCount;
Data=(CData*)map;
return true;
}
//Try to create new file map
inline bool New(char *name, int DCount=BlockSize)
{
Close();
file=CreateFile(
name,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(INVALID_HANDLE_VALUE==file) return false;
FileSize=sizeof(CData)*DCount;
mapping = CreateFileMapping(file, NULL, PAGE_READWRITE, 0, FileSize, NULL);
if(NULL==mapping) return false;
map = MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, FileSize);
if(NULL==map) return false;
DataCount=DCount;
PrivateDataCount=DataCount;
Data=(CData*)map;
return true;
}
//Try to resize file map
inline bool Resize(int DCount)
{
if(DCount==PrivateDataCount) return true;
if(NULL!=map)
{
UnmapViewOfFile(map);
map=NULL;
}
if(NULL!=mapping)
{
CloseHandle(mapping);
mapping=NULL;
}
PrivateDataCount=0;
DataCount=0;
Data=NULL;
if(DCount<0)DCount=0;
FileSize=sizeof(CData)*DCount;
if(SetFilePointer(file, FileSize, NULL, FILE_BEGIN)==0xFFFFFFFF)
return false;
if(!SetEndOfFile(file)) return false;
mapping = CreateFileMapping(file, NULL, PAGE_READWRITE, 0, FileSize, NULL);
if(NULL==mapping) return false;
map = MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, FileSize);
if(NULL==map) return false;
DataCount=DCount;
PrivateDataCount=DataCount;
Data=(CData*)map;
return true;
}
//Try to resize file map with block size
inline bool ResizeB(int DCount)
{
return Resize(((DCount-1)/BlockSize+1)*BlockSize);
}
//No comments :-)
inline bool isReady()
{
return NULL!=map;
}
//operator [] for safe access
inline CData& operator[](const int i)
{
if(NULL==map) return ErrAddr;
if(i<0) return ErrAddr;
else if(i>=PrivateDataCount) if(!ResizeB(i+1)) return ErrAddr;
return (*((CData*)map+i));
}
//Put buffer to file map
inline bool Put(const int pos, CData* buf, const int len)
{
int i;
i=pos+len+1;
if(i>PrivateDataCount) if(!ResizeB(i)) return false;
for(i=0;i<len;i++) ((CData*)map)[pos+i]=buf[i];
return true;
}
//Get buffer from file map
inline bool Get(const int pos, CData* buf, const int len)
{
int i;
i=pos+len+1;
if(i>PrivateDataCount) return false;
for(i=0;i<len;i++) buf[i]=((CData*)map)[pos+i];
return true;
}
};
#endif