298 lines
8.5 KiB
C
298 lines
8.5 KiB
C
/*
|
|
**************************************************************************************************
|
|
* CPA_Ed_1 team *
|
|
* File Management *
|
|
**************************************************************************************************
|
|
*/
|
|
|
|
#include "Stdinc.h"
|
|
|
|
|
|
#include "File.h"
|
|
#include "Types.h"
|
|
|
|
|
|
#ifdef LDT_USE_SINGLE_FILE_BUFFER
|
|
|
|
char* GBuff = NULL;
|
|
unsigned long GBuffSize = 0;
|
|
#define GBuffMargin (1024*50) /* 50k above the file size */
|
|
|
|
#endif
|
|
|
|
/*
|
|
* OPEN a file for reading
|
|
* --------------------------------------------------------------
|
|
* _pInfoMemFile : the value returned
|
|
* _Name : Name of the file.
|
|
* Return : Error code(zero for none)
|
|
* --------------------------------------------------------------
|
|
* Conditions : If the file does not exist or cannot be found, the fopen call fails.
|
|
* --------------------------------------------------------------
|
|
* Comments : If succes, the pointer value not NULL
|
|
* A null pointer value indicates an error.
|
|
* If some errors occur, then all space are free
|
|
*/
|
|
//#define OVERLAPPED_
|
|
#ifdef OVERLAPPED_
|
|
#define OVERLAPPED_NO_BUFFERING
|
|
long f_OpenMem(LDT_tdst_MemFile **_pInfoMemFile,char* _Name)
|
|
{
|
|
long Err = LDT_EI_Err_None;
|
|
|
|
*_pInfoMemFile= (LDT_tdst_MemFile *)malloc(sizeof(LDT_tdst_MemFile));
|
|
|
|
if(*_pInfoMemFile)
|
|
{
|
|
HANDLE File;
|
|
|
|
(*_pInfoMemFile)->sPathLength = 0;
|
|
(*_pInfoMemFile)->pName= (char *)malloc(( strlen(_Name)+1 ));
|
|
strcpy((*_pInfoMemFile)->pName , _Name);
|
|
(*_pInfoMemFile)->pBuffer = NULL;
|
|
|
|
#ifdef OVERLAPPED_NO_BUFFERING
|
|
File = CreateFile( _Name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED|FILE_FLAG_NO_BUFFERING, NULL);
|
|
#else
|
|
File = CreateFile( _Name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
|
|
#endif
|
|
if(File != INVALID_HANDLE_VALUE)
|
|
{
|
|
(*_pInfoMemFile)->Size = GetFileSize( File, NULL);
|
|
if((*_pInfoMemFile)->Size)
|
|
{
|
|
DWORD BoundSize, VolumeSectorsize, SectorsPerCluster, NumberOfFreeClusters, TotalNumberOfClusters ;
|
|
char Drive[4] = "C:\\";
|
|
if(_Name[1] == ':') Drive[0] = _Name[0];
|
|
GetDiskFreeSpace(_Name[1] == ':'? Drive: NULL, &SectorsPerCluster, &VolumeSectorsize, &NumberOfFreeClusters, &TotalNumberOfClusters );
|
|
|
|
#ifdef OVERLAPPED_NO_BUFFERING
|
|
BoundSize = (*_pInfoMemFile)->Size + 5 + VolumeSectorsize;
|
|
BoundSize -= BoundSize%VolumeSectorsize;
|
|
(*_pInfoMemFile)->pBuffer= (char*)VirtualAlloc( NULL, BoundSize, MEM_COMMIT, PAGE_READWRITE );
|
|
#else
|
|
BoundSize = (*_pInfoMemFile)->Size + 5;
|
|
(*_pInfoMemFile)->pBuffer= (char*)malloc( BoundSize );
|
|
#endif
|
|
if((*_pInfoMemFile)->pBuffer)
|
|
{
|
|
OVERLAPPED overlapped;
|
|
overlapped.Offset = overlapped.OffsetHigh = 0;
|
|
overlapped.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
|
|
ReadFile( File, (*_pInfoMemFile)->pBuffer, BoundSize, NULL, &overlapped);
|
|
WaitForSingleObject( overlapped.hEvent, INFINITE);
|
|
CloseHandle(overlapped.hEvent);
|
|
|
|
(*_pInfoMemFile)->Pos = 0;
|
|
strcpy((*_pInfoMemFile)->pBuffer+(*_pInfoMemFile)->Size , "\n\"\n\n");
|
|
}
|
|
else Err = LDT_EI_Err_Malloc;
|
|
}
|
|
else Err = LDT_EI_Err_SeekFile;
|
|
CloseHandle(File);
|
|
}
|
|
else Err = LDT_EI_Err_OpenFile;
|
|
}
|
|
else Err = LDT_EI_Err_Malloc;
|
|
|
|
if( Err != LDT_EI_Err_None && *_pInfoMemFile )
|
|
{
|
|
free((*_pInfoMemFile)->pName);
|
|
#ifndef LDT_USE_SINGLE_FILE_BUFFER
|
|
if((*_pInfoMemFile)->pBuffer) free((*_pInfoMemFile)->pBuffer);
|
|
#endif
|
|
|
|
free((*_pInfoMemFile));
|
|
*_pInfoMemFile = NULL;
|
|
}
|
|
return Err;
|
|
}
|
|
|
|
#else
|
|
|
|
long f_OpenMem(LDT_tdst_MemFile **_pInfoMemFile,char* _Name)
|
|
{
|
|
long Err = LDT_EI_Err_None;
|
|
FILE *pFile; /* Pointer of the file */
|
|
|
|
*_pInfoMemFile= (LDT_tdst_MemFile *)malloc(sizeof(LDT_tdst_MemFile));
|
|
|
|
if(*_pInfoMemFile)
|
|
{
|
|
(*_pInfoMemFile)->sPathLength = 0;
|
|
(*_pInfoMemFile)->pName= (char *)malloc(( strlen(_Name)+1 ));
|
|
strcpy((*_pInfoMemFile)->pName , _Name);
|
|
|
|
(*_pInfoMemFile)->pBuffer = NULL;
|
|
pFile = fopen(_Name, "rb");
|
|
if(pFile)
|
|
{
|
|
(*_pInfoMemFile)->Size = _filelength (_fileno(pFile));
|
|
if((*_pInfoMemFile)->Size)
|
|
{
|
|
#ifdef LDT_USE_SINGLE_FILE_BUFFER
|
|
if(GBuffSize < (*_pInfoMemFile)->Size)
|
|
{
|
|
if(GBuff) free(GBuff);
|
|
GBuff = malloc( GBuffSize = (*_pInfoMemFile)->Size + 5 + GBuffMargin);
|
|
}
|
|
(*_pInfoMemFile)->pBuffer = GBuff;
|
|
#else
|
|
(*_pInfoMemFile)->pBuffer= (char*) malloc(((*_pInfoMemFile)->Size + 5 ));
|
|
#endif
|
|
if((*_pInfoMemFile)->pBuffer)
|
|
{
|
|
if(fread((*_pInfoMemFile)->pBuffer,(*_pInfoMemFile)->Size,1,pFile))
|
|
{
|
|
(*_pInfoMemFile)->Pos = 0;
|
|
strcpy((*_pInfoMemFile)->pBuffer+(*_pInfoMemFile)->Size , "\n\"\n\n");
|
|
}
|
|
else Err = LDT_EI_Err_ReadFile;
|
|
}
|
|
else Err = LDT_EI_Err_Malloc;
|
|
}
|
|
else Err = LDT_EI_Err_SeekFile;
|
|
fclose(pFile);
|
|
}
|
|
else Err = LDT_EI_Err_OpenFile;
|
|
}
|
|
else Err = LDT_EI_Err_Malloc;
|
|
|
|
if( Err != LDT_EI_Err_None && *_pInfoMemFile )
|
|
{
|
|
free((*_pInfoMemFile)->pName);
|
|
|
|
#ifndef LDT_USE_SINGLE_FILE_BUFFER
|
|
if((*_pInfoMemFile)->pBuffer) free((*_pInfoMemFile)->pBuffer);
|
|
#endif
|
|
|
|
free((*_pInfoMemFile));
|
|
*_pInfoMemFile = NULL;
|
|
}
|
|
return Err;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/*
|
|
* READ a piece of file from memory
|
|
* --------------------------------------------------------------
|
|
* _PointerDest : Address of the destination
|
|
* _Size : size of data to move (in bytes)
|
|
* _pInfoMemFile : Source file address in memory
|
|
* Return : error code if <0 or the Size of data moved(for none error)
|
|
* --------------------------------------------------------------
|
|
* Conditions :
|
|
* --------------------------------------------------------------
|
|
* Comments : If succes, the return value are the Size of data moved
|
|
* A value<0 indicate an error
|
|
*/
|
|
long f_ReadMem(char * _PointerDest,size_t _Size,LDT_tdst_MemFile *_pInfoMemFile )
|
|
{
|
|
long Err;
|
|
|
|
/*if( (_pInfoMemFile->Pos < _pInfoMemFile->Size) && */
|
|
if (_pInfoMemFile->Size -_pInfoMemFile->Pos >= _Size)
|
|
{
|
|
if(_PointerDest == memmove(_PointerDest,_pInfoMemFile->pBuffer+_pInfoMemFile->Pos,_Size))
|
|
{
|
|
_pInfoMemFile->Pos += _Size;
|
|
return _Size;
|
|
}
|
|
else
|
|
Err = -LDT_EI_Err_MemMove;
|
|
}
|
|
else
|
|
Err = -LDT_EI_Err_NotEnoughDataForMove;
|
|
|
|
return Err;
|
|
}
|
|
|
|
/*
|
|
* CLOSE a file (in memory and stream)
|
|
* --------------------------------------------------------------
|
|
* _pInfoMemFile : Source file address in memory
|
|
* Return : error code
|
|
* --------------------------------------------------------------
|
|
* Conditions : close an open stream
|
|
* --------------------------------------------------------------
|
|
* Comments : fclose returns 0 if the stream is successfully closed
|
|
* return EOF to indicate an error..
|
|
* Return value must be int
|
|
*/
|
|
long f_CloseMem(LDT_tdst_MemFile *_pInfoMemFile)
|
|
{
|
|
#ifdef LDT_MULTITHREADED
|
|
#ifdef OVERLAPPED_NO_BUFFERING
|
|
VirtualFree( _pInfoMemFile->pBuffer, 0, MEM_RELEASE);
|
|
#else
|
|
free( _pInfoMemFile->pBuffer );
|
|
#endif
|
|
#else
|
|
#ifndef LDT_USE_SINGLE_FILE_BUFFER
|
|
free(_pInfoMemFile->pBuffer);
|
|
#endif
|
|
#endif
|
|
free(_pInfoMemFile->pName);
|
|
free(_pInfoMemFile);
|
|
return LDT_EI_Err_None;
|
|
}
|
|
|
|
/*
|
|
* SEEK a file in memory to a given position.
|
|
* --------------------------------------------------------------
|
|
* _File : File to seek.
|
|
* _Offset : Offset to seek.
|
|
* _Origin : SEEK_SET or SEEK_END.
|
|
* Return : error code
|
|
* --------------------------------------------------------------
|
|
* Conditions : The argument origin must be one of the following constant:
|
|
* -SEEK_CUR Current position of file pointer
|
|
* -SEEK_END End of file
|
|
* -SEEK_SET Beginning of file
|
|
* --------------------------------------------------------------
|
|
* Comments : If successful, fseek returns 0
|
|
* Return value must be long
|
|
*/
|
|
long f_SeekMem(LDT_tdst_MemFile *_pInfoMemFile ,long _Offset,int _Origin)
|
|
{
|
|
long Err;
|
|
|
|
|
|
Err = LDT_EI_Err_None;
|
|
switch (_Origin)
|
|
{
|
|
case SEEK_SET:
|
|
if(_Offset>=0 && _pInfoMemFile->Size >= (size_t)_Offset)
|
|
_pInfoMemFile->Pos = _Offset;
|
|
else
|
|
Err = LDT_EI_Err_SeekInMem;
|
|
break;
|
|
case SEEK_CUR:
|
|
if(_Offset>0 && ((_pInfoMemFile->Size-_pInfoMemFile->Pos) >= (size_t)_Offset) )
|
|
_pInfoMemFile->Pos += _Offset;
|
|
else if( _Offset<0 && (_pInfoMemFile->Pos >= (size_t)(-_Offset)))
|
|
_pInfoMemFile->Pos += _Offset;
|
|
else
|
|
Err = LDT_EI_Err_SeekInMem;
|
|
break;
|
|
case SEEK_END:
|
|
if(_Offset <= 0 && (_pInfoMemFile->Size >= (size_t)(-_Offset)))
|
|
_pInfoMemFile->Pos = _Offset+_pInfoMemFile->Size;
|
|
else
|
|
Err = LDT_EI_Err_SeekInMem;
|
|
break;
|
|
default:
|
|
Err = LDT_EI_Err_SeekInMem;
|
|
}
|
|
|
|
return Err;
|
|
}
|
|
|
|
|
|
long f_TellMem(LDT_tdst_MemFile *_pInfoMemFile )
|
|
{
|
|
return _pInfoMemFile->Pos;
|
|
}
|