📄 ffilemanageransi.h
字号:
/*=============================================================================
FFileManagerAnsi.h: Unreal ANSI C based file manager.
Copyright 1997-1999 Epic Games, Inc. All Rights Reserved.
Revision history:
* Created by Tim Sweeney
=============================================================================*/
#include "FFileManagerGeneric.h"
/*-----------------------------------------------------------------------------
File Manager.
-----------------------------------------------------------------------------*/
// File manager.
class FArchiveFileReader : public FArchive
{
public:
FArchiveFileReader( FILE* InFile, FOutputDevice* InError, INT InSize )
: File ( InFile )
, Error ( InError )
, Size ( InSize )
, Pos ( 0 )
, BufferBase ( 0 )
, BufferCount ( 0 )
{
guard(FArchiveFileReader::FArchiveFileReader);
fseek( File, 0, SEEK_SET );
ArIsLoading = ArIsPersistent = 1;
unguard;
}
~FArchiveFileReader()
{
guard(FArchiveFileReader::~FArchiveFileReader);
if( File )
Close();
unguard;
}
void Precache( INT HintCount )
{
guardSlow(FArchiveFileReader::Precache);
checkSlow(Pos==BufferBase+BufferCount);
BufferBase = Pos;
BufferCount = Min( Min( HintCount, (INT)(ARRAY_COUNT(Buffer) - (Pos&(ARRAY_COUNT(Buffer)-1))) ), Size-Pos );
if( fread( Buffer, BufferCount, 1, File )!=1 )
{
ArIsError = 1;
Error->Logf( TEXT("fread failed: BufferCount=%i Error=%i"), BufferCount, ferror(File) );
return;
}
unguardSlow;
}
void Seek( INT InPos )
{
guard(FArchiveFileReader::Seek);
check(InPos>=0);
check(InPos<=Size);
if( fseek(File,InPos,SEEK_SET) )
{
ArIsError = 1;
Error->Logf( TEXT("seek Failed %i/%i: %i %i"), InPos, Size, Pos, ferror(File) );
}
Pos = InPos;
BufferBase = Pos;
BufferCount = 0;
unguard;
}
INT Tell()
{
return Pos;
}
INT TotalSize()
{
return Size;
}
UBOOL Close()
{
guardSlow(FArchiveFileReader::Close);
if( File )
fclose( File );
File = NULL;
return !ArIsError;
unguardSlow;
}
void Serialize( void* V, INT Length )
{
guardSlow(FArchiveFileReader::Serialize);
while( Length>0 )
{
INT Copy = Min( Length, BufferBase+BufferCount-Pos );
if( Copy==0 )
{
if( Length >= ARRAY_COUNT(Buffer) )
{
if( fread( V, Length, 1, File )!=1 )
{
ArIsError = 1;
Error->Logf( TEXT("fread failed: Length=%i Error=%i"), Length, ferror(File) );
}
Pos += Length;
BufferBase += Length;
return;
}
Precache( MAXINT );
if( ArIsError )
return;
Copy = Min( Length, BufferBase+BufferCount-Pos );
check(Copy>0);
}
appMemcpy( V, Buffer+Pos-BufferBase, Copy );
Pos += Copy;
Length -= Copy;
V = (BYTE*)V + Copy;
}
unguardSlow;
}
protected:
FILE* File;
FOutputDevice* Error;
INT Size;
INT Pos;
INT BufferBase;
INT BufferCount;
BYTE Buffer[1024];
};
class FArchiveFileWriter : public FArchive
{
public:
FArchiveFileWriter( FILE* InFile, FOutputDevice* InError )
: File (InFile)
, Error ( InError )
, Pos (0)
, BufferCount (0)
{}
~FArchiveFileWriter()
{
guard(FArchiveFileWriter::~FArchiveFileWriter);
if( File )
Close();
File = NULL;
unguard;
}
void Seek( INT InPos )
{
Flush();
if( fseek(File,InPos,SEEK_SET) )
{
ArIsError = 1;
Error->Logf( LocalizeError("SeekFailed",TEXT("Core")) );
}
Pos = InPos;
}
INT Tell()
{
return Pos;
}
UBOOL Close()
{
guardSlow(FArchiveFileWriter::Close);
Flush();
if( File && fclose( File ) )
{
ArIsError = 1;
Error->Logf( LocalizeError("WriteFailed",TEXT("Core")) );
}
return !ArIsError;
unguardSlow;
}
void Serialize( void* V, INT Length )
{
Pos += Length;
INT Copy;
while( Length > (Copy=ARRAY_COUNT(Buffer)-BufferCount) )
{
appMemcpy( Buffer+BufferCount, V, Copy );
BufferCount += Copy;
Length -= Copy;
V = (BYTE*)V + Copy;
Flush();
}
if( Length )
{
appMemcpy( Buffer+BufferCount, V, Length );
BufferCount += Length;
}
}
void Flush()
{
if( BufferCount && fwrite( Buffer, BufferCount, 1, File )!=1 )
{
ArIsError = 1;
Error->Logf( LocalizeError("WriteFailed",TEXT("Core")) );
}
BufferCount=0;
}
protected:
FILE* File;
FOutputDevice* Error;
INT Pos;
INT BufferCount;
BYTE Buffer[4096];
};
class FFileManagerAnsi : public FFileManagerGeneric
{
public:
FArchive* CreateFileReader( const TCHAR* Filename, FOutputDevice* Error )
{
guard(FFileManagerAnsi::CreateFileReader);
FILE* File = TCHAR_CALL_OS(_wfopen(Filename,TEXT("rb")),fopen(TCHAR_TO_ANSI(Filename),TCHAR_TO_ANSI(TEXT("rb"))));
if( !File )
return NULL;
fseek( File, 0, SEEK_END );
return new(TEXT("AnsiFileReader"))FArchiveFileReader(File,Error,ftell(File));
unguard;
}
FArchive* CreateFileWriter( const TCHAR* Filename, UBOOL ReplaceExisting, UBOOL EvenIfReadOnly, UBOOL Unbuffered, UBOOL Append, FOutputDevice* Error )
{
guard(FFileManagerAnsi::CreateFileWriter);
if( EvenIfReadOnly )
TCHAR_CALL_OS(_wchmod(Filename, _S_IREAD | _S_IWRITE),_chmod(TCHAR_TO_ANSI(Filename), _S_IREAD | _S_IWRITE));
if( !ReplaceExisting && FileSize(Filename)>=0 )
return NULL;
const TCHAR* Mode = Append ? TEXT("ab") : TEXT("wb");
FILE* File = TCHAR_CALL_OS(_wfopen(Filename,Mode),fopen(TCHAR_TO_ANSI(Filename),TCHAR_TO_ANSI(Mode)));
if( !File )
return NULL;
if( Unbuffered )
setvbuf( File, 0, _IONBF, 0 );
return new(TEXT("AnsiFileWriter"))FArchiveFileWriter(File,Error);
unguard;
}
UBOOL Delete( const TCHAR* Filename, UBOOL RequireExists=0, UBOOL EvenReadOnly=0 )
{
guard(FFileManagerAnsi::Delete);
if( EvenReadOnly )
TCHAR_CALL_OS(_wchmod(Filename, _S_IREAD | _S_IWRITE),_chmod(TCHAR_TO_ANSI(Filename), _S_IREAD | _S_IWRITE));
return TCHAR_CALL_OS(_wunlink(Filename),_unlink(TCHAR_TO_ANSI(Filename)))==0 || (errno==ENOENT && !RequireExists);
unguard;
}
SQWORD GetGlobalTime( const TCHAR* Filename )
{
guard(FFileManagerAnsi::GetGlobalTime);
// Not yet spec'd, implemented!!
return 0;
unguard;
}
UBOOL SetGlobalTime( const TCHAR* Filename )
{
guard(FFileManagerAnsi::SetGlobalTime);
// Not yet spec'd, implemented!!
return 0;
unguard;
}
UBOOL MakeDirectory( const TCHAR* Path, UBOOL Tree=0 )
{
guard(FFileManagerAnsi::MakeDirectory);
if( Tree )
return FFileManagerGeneric::MakeDirectory( Path, Tree );
//warning: ANSI compliance is questionable here.
return TCHAR_CALL_OS( _wmkdir(Path), _mkdir(TCHAR_TO_ANSI(Path)) )==0 || errno==EEXIST;
unguard;
}
UBOOL DeleteDirectory( const TCHAR* Path, UBOOL RequireExists=0, UBOOL Tree=0 )
{
guard(FFileManagerAnsi::DeleteDirectory);
if( Tree )
return FFileManagerGeneric::DeleteDirectory( Path, RequireExists, Tree );
//warning: ANSI compliance is questionable here.
return TCHAR_CALL_OS( _wrmdir(Path), _rmdir(TCHAR_TO_ANSI(Path)) )==0 || (errno==ENOENT && !RequireExists);
unguard;
}
TArray<FString> FindFiles( const TCHAR* Filename, UBOOL Files, UBOOL Directories )
{
guard(FFileManagerAnsi::FindFiles);
//warning: ANSI compliance is questionable here.
TArray<FString> Result;
#if UNICODE
if( GUnicodeOS )
{
_wfinddata_t Found;
long hFind = _wfindfirst( Filename, &Found );
if( hFind != -1 )
do
if
( appStrcmp(Found.name,TEXT("."))!=0
&& appStrcmp(Found.name,TEXT(".."))!=0
&& ((Found.attrib & _A_SUBDIR) ? Directories : Files) )
new(Result)FString( Found.name );
while( _wfindnext( hFind, &Found )!=-1 );
_findclose(hFind);
}
else
#endif
{
_finddata_t Found;
long hFind = _findfirst( TCHAR_TO_ANSI(Filename), &Found );
if( hFind != -1 )
{
do
{
const TCHAR* Name = ANSI_TO_TCHAR(Found.name);
if
( appStrcmp(Name,TEXT("."))!=0
&& appStrcmp(Name,TEXT(".."))!=0
&& ((Found.attrib & _A_SUBDIR) ? Directories : Files) )
new(Result)FString( Name );
}
while( _findnext( hFind, &Found )!=-1 );
}
_findclose(hFind);
}
return Result;
unguard;
}
UBOOL SetCurrentDirectory( const TCHAR* Filename )
{
guard(FFileManagerAnsi::SetCurrentDirectory);
//warning: ANSI compliance is questionable here.
return TCHAR_CALL_OS( _wchdir(Filename), chdir(TCHAR_TO_ANSI(Filename)) )==0;
unguard;
}
FString GetCurrentDirectory()
{
guard(FFileManagerAnsi::GetCurrentDirectory);
//warning: ANSI compliance is questionable here.
#if UNICODE
if( GUnicodeOS )
{
TCHAR Buffer[1024]=TEXT("");
_wgetcwd(Buffer,ARRAY_COUNT(Buffer));
return FString(Buffer);
}
else
#endif
{
ANSICHAR Buffer[1024]="";
getcwd( Buffer, ARRAY_COUNT(Buffer) );
return appFromAnsi( Buffer );//!!return TCHAR_TO_ANSI is fucked up by Visual C++.
}
unguard;
}
};
/*-----------------------------------------------------------------------------
The End.
-----------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -