Обертка для FileMap
От: WolfHound  
Дата: 19.08.02 15:59
Оценка:
Принемаются любые замечания в том числе к моему корявому английскому
//(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
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.