Code:
#define PAGE_INITIALIZED 0x2A3B4C
typedef struct _INDEX_ITEM{
DWORD dwSize;
char* lpData;
} INDEX_ITEM;
typedef struct _PAGE_INDEX{
DWORD dwInit;
HANDLE hHeap;
DWORD dwPages;
INDEX_ITEM* lpPages;
} PAGE_INDEX;
//this must be called first
bool PG_Init(PAGE_INDEX* lpIndex){
if(!lpIndex){ return false; }
lpIndex->dwPages=0;
lpIndex->lpPages=NULL;
lpIndex->hHeap=HeapCreate(0,0x1000,0);
if(!lpIndex->hHeap){
return false;
}
lpIndex->dwInit=PAGE_INITIALIZED;
return true;
}
//this must be called if you're done with it
void PG_Deinit(PAGE_INDEX* lpIndex){
if(!lpIndex||lpIndex->dwInit!=PAGE_INITIALIZED){ return; }
for(int i=0;i<lpIndex->dwPages;i++){
if(lpIndex->lpPages[i].dwSize&&lpIndex->lpPages[i].lpData){
HeapFree(lpIndex->hHeap,0,lpIndex->lpPages[i].lpData);
}
}
HeapFree(lpIndex->hHeap,0,lpIndex->lpPages);
HeapDestroy(lpIndex->hHeap);
lpIndex->dwPages=0;
lpIndex->lpPages=NULL;
lpIndex->dwInit=0;
}
//creates a new page and returns its ID
int PG_CreatePage(PAGE_INDEX* lpIndex){
if(!lpIndex||lpIndex->dwInit!=PAGE_INITIALIZED){ return -1; }
if(!lpIndex->lpPages){
lpIndex->lpPages=(INDEX_ITEM*)HeapAlloc(lpIndex->hHeap,HEAP_ZERO_MEMORY,32*sizeof(INDEX_ITEM));
}
else if(!(lpIndex->dwPages%32)){
lpIndex->lpPages=(INDEX_ITEM*)HeapReAlloc(lpIndex->hHeap,HEAP_ZERO_MEMORY,lpIndex->lpPages,
(((lpIndex->dwPages>>5)+1)<<5)*sizeof(INDEX_ITEM));
}
lpIndex->lpPages[lpIndex->dwPages].dwSize=0;
lpIndex->lpPages[lpIndex->dwPages].lpData=NULL;
lpIndex->dwPages++;
return lpIndex->dwPages-1;
}
//you can set binary data to a page with this
bool PG_SetPageRawData(PAGE_INDEX* lpIndex,DWORD dwId,char* lpData,DWORD dwSize){
char* lpBkupData;
INDEX_ITEM* lpCur;
if(!lpData||!dwSize||!lpIndex||lpIndex->dwInit!=PAGE_INITIALIZED||
dwId>=lpIndex->dwPages){ return false; }
lpCur=(&(lpIndex->lpPages[dwId]));
if(dwSize>lpCur->dwSize){
if(!lpCur->lpData){
lpCur->lpData=(char*)HeapAlloc(lpIndex->hHeap,HEAP_ZERO_MEMORY,dwSize);
if(!lpCur->lpData){
return false;
}
lpCur->dwSize=dwSize;
}
else{
lpBkupData=lpCur->lpData;
lpCur->lpData=(char*)HeapReAlloc(lpIndex->hHeap,HEAP_ZERO_MEMORY,lpCur->lpData,dwSize);
if(!lpCur->lpData){
lpCur->lpData=lpBkupData;
return false;
}
lpCur->dwSize=dwSize;
}
}
for(int i=0;i<dwSize;i++){
lpCur->lpData[i]=lpData[i];
}
return true;
}
//you can assign text to a page with this
bool PG_SetPageText(PAGE_INDEX* lpIndex,DWORD dwId,char* lpData){
int len;
for(len=0;lpData[len];len++);
return PG_SetPageRawData(lpIndex,dwId,lpData,len+1);
}
//gets the text buffer size, use when copying the buffer data to a new buffer
DWORD PG_GetPageBufferSize(PAGE_INDEX* lpIndex,DWORD dwId){
if(!lpIndex||lpIndex->dwInit!=PAGE_INITIALIZED){ return 0; }
return lpIndex->lpPages[dwId].dwSize;
}
//get the pointer to the specified page's buffer
char* PG_GetPageBuffer(PAGE_INDEX* lpIndex,DWORD dwId){
if(!lpIndex||lpIndex->dwInit!=PAGE_INITIALIZED){ return 0; }
return lpIndex->lpPages[dwId].lpData;
}
//get the number of pages
DWORD PG_GetNumOfPages(PAGE_INDEX* lpIndex){
if(!lpIndex||lpIndex->dwInit!=PAGE_INITIALIZED){ return 0; }
return lpIndex->dwPages;
}
//save it all to a file
bool PG_SaveToFile(PAGE_INDEX* lpIndex,char* lpFileName){
HANDLE hFile;
DWORD dwWritten,dwLine,dwZero=0;
if(!lpIndex||!lpFileName||lpIndex->dwInit!=PAGE_INITIALIZED){ return false; }
hFile=CreateFileA(lpFileName,GENERIC_WRITE,7,0,CREATE_ALWAYS,0,0);
if(hFile==INVALID_HANDLE_VALUE){
return false;
}
WriteFile(hFile,&(lpIndex->dwPages),4,&dwWritten,0);
dwLine=4+lpIndex->dwPages*8;
for(int i=0;i<lpIndex->dwPages;i++){
WriteFile(hFile,&(lpIndex->lpPages[i].dwSize),4,&dwWritten,0);
WriteFile(hFile,&dwLine,4,&dwWritten,0);
dwLine+=lpIndex->lpPages[i].dwSize;
}
for(int i=0;i<lpIndex->dwPages;i++){
WriteFile(hFile,lpIndex->lpPages[i].lpData,lpIndex->lpPages[i].dwSize,&dwWritten,0);
}
CloseHandle(hFile);
return true;
}
//load it all from a file
bool PG_LoadFromFile(PAGE_INDEX* lpIndex,char* lpFileName){
HANDLE hFile;
DWORD dwRead,dwPointer,dwNewPointer,dwPages;
if(!lpIndex||lpIndex->dwInit!=PAGE_INITIALIZED){ return false; }
hFile=CreateFileA(lpFileName,GENERIC_READ,7,0,OPEN_ALWAYS,0,0);
if(hFile==INVALID_HANDLE_VALUE){
return false;
}
ReadFile(hFile,&dwPages,4,&dwRead,0);
for(int i=0;i<dwPages;i++){
PG_CreatePage(lpIndex);
ReadFile(hFile,&(lpIndex->lpPages[i].dwSize),4,&dwRead,0);
lpIndex->lpPages[i].lpData=(char*)HeapAlloc(lpIndex->hHeap,0,lpIndex->lpPages[i].dwSize);
ReadFile(hFile,&dwNewPointer,4,&dwRead,0);
dwPointer=SetFilePointer(hFile,0,0,FILE_CURRENT);
SetFilePointer(hFile,dwNewPointer,0,FILE_BEGIN);
ReadFile(hFile,lpIndex->lpPages[i].lpData,lpIndex->lpPages[i].dwSize,&dwRead,0);
SetFilePointer(hFile,dwPointer,0,FILE_BEGIN);
}
CloseHandle(hFile);
return true;
}
An example to use:
Code:
char* buf;
DWORD dwPages;
PAGE_INDEX pgi;
if(PG_Init(&pgi)){
PG_SetPageText(&pgi,PG_CreatePage(&pgi),"This is on the page 1");
PG_SetPageText(&pgi,PG_CreatePage(&pgi),"This is on the page 2");
PG_SetPageText(&pgi,PG_CreatePage(&pgi),"This is on the page 3");
PG_SaveToFile(&pgi,"test.txt");
PG_Deinit(&pgi);
}
if(PG_Init(&pgi)){
PG_LoadFromFile(&pgi,"test.txt");
dwPages=PG_GetNumOfPages(&pgi);
for(int i=0;i<dwPages;i++){
buf=PG_GetPageBuffer(&pgi,i);
if(buf){
MessageBox(0,buf,"Contents of a page",MB_OK);
}
}
PG_Deinit(&pgi);
}
Actually I think I should retire from trying to confuse beginners...