reman3/Rayman_X/cpa/tempgrp/ldt/Src/File.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;
}