diff options
Diffstat (limited to 'utils/vmpi/vmpi_filesystem.cpp')
| -rw-r--r-- | utils/vmpi/vmpi_filesystem.cpp | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/utils/vmpi/vmpi_filesystem.cpp b/utils/vmpi/vmpi_filesystem.cpp new file mode 100644 index 0000000..815f918 --- /dev/null +++ b/utils/vmpi/vmpi_filesystem.cpp @@ -0,0 +1,366 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "vmpi_filesystem_internal.h" +#include "tier1/utlbuffer.h" + + +bool g_bDisableFileAccess = false; + + +CBaseVMPIFileSystem *g_pBaseVMPIFileSystem = NULL; +IFileSystem *g_pOriginalPassThruFileSystem = NULL; + +void* GetVMPIFileSystem() +{ + return (IBaseFileSystem*)g_pBaseVMPIFileSystem; +} + +EXPOSE_INTERFACE_FN( GetVMPIFileSystem, IBaseFileSystem, BASEFILESYSTEM_INTERFACE_VERSION ) + + +IFileSystem* VMPI_FileSystem_Init( int maxMemoryUsage, IFileSystem *pPassThru ) +{ + Assert( g_bUseMPI ); + Assert( !g_pBaseVMPIFileSystem ); + g_pOriginalPassThruFileSystem = pPassThru; + + if ( g_bMPIMaster ) + { + extern CBaseVMPIFileSystem* CreateMasterVMPIFileSystem( int maxMemoryUsage, IFileSystem *pPassThru ); + CreateMasterVMPIFileSystem( maxMemoryUsage, pPassThru ); + } + else + { + extern CBaseVMPIFileSystem* CreateWorkerVMPIFileSystem(); + CreateWorkerVMPIFileSystem(); + } + + // The Create function should have set this. Normally, we'd set g_pBaseVMPIFileSystem right here, but + // the create functions may want to receive some messages, in which case they need to set g_pBaseVMPIFileSystem + // so the packets get routed appropriately. + Assert( g_pBaseVMPIFileSystem ); + return g_pBaseVMPIFileSystem; +} + + +IFileSystem* VMPI_FileSystem_Term() +{ + if ( g_pBaseVMPIFileSystem ) + { + g_pBaseVMPIFileSystem->Release(); + g_pBaseVMPIFileSystem = NULL; + + if ( g_iVMPIVerboseLevel >= 1 ) + { + if ( g_bMPIMaster ) + Msg( "Multicast send: %dk\n", (g_nMulticastBytesSent + 511) / 1024 ); + else + Msg( "Multicast recv: %dk\n", (g_nMulticastBytesReceived + 511) / 1024 ); + } + } + + IFileSystem *pRet = g_pOriginalPassThruFileSystem; + g_pOriginalPassThruFileSystem = NULL; + return pRet; +} + + +void VMPI_FileSystem_DisableFileAccess() +{ + g_bDisableFileAccess = true; +} + + +CreateInterfaceFn VMPI_FileSystem_GetFactory() +{ + return Sys_GetFactoryThis(); +} + + +void VMPI_FileSystem_CreateVirtualFile( const char *pFilename, const void *pData, unsigned long fileLength ) +{ + g_pBaseVMPIFileSystem->CreateVirtualFile( pFilename, pData, fileLength ); +} + + +// Register our packet ID. +bool FileSystemRecv( MessageBuffer *pBuf, int iSource, int iPacketID ) +{ + if ( g_pBaseVMPIFileSystem ) + return g_pBaseVMPIFileSystem->HandleFileSystemPacket( pBuf, iSource, iPacketID ); + else + return false; +} + + +CDispatchReg g_DispatchReg_FileSystem( VMPI_PACKETID_FILESYSTEM, FileSystemRecv ); + + + +// ------------------------------------------------------------------------------------------------------------------------ // +// CVMPIFile_Memory implementation. +// ------------------------------------------------------------------------------------------------------------------------ // + +void CVMPIFile_Memory::Init( const char *pData, long len, char chMode /* = 'b' */ ) +{ + m_pData = pData; + m_DataLen = len; + m_iCurPos = 0; + m_chMode = chMode; +} + +void CVMPIFile_Memory::Close() +{ + delete this; +} + +void CVMPIFile_Memory::Seek( int pos, FileSystemSeek_t seekType ) +{ + if ( seekType == FILESYSTEM_SEEK_HEAD ) + m_iCurPos = pos; + else if ( seekType == FILESYSTEM_SEEK_CURRENT ) + m_iCurPos += pos; + else + m_iCurPos = m_DataLen - pos; +} + +unsigned int CVMPIFile_Memory::Tell() +{ + return m_iCurPos; +} + +unsigned int CVMPIFile_Memory::Size() +{ + return m_DataLen; +} + +void CVMPIFile_Memory::Flush() +{ +} + +int CVMPIFile_Memory::Read( void* pOutput, int size ) +{ + Assert( m_iCurPos >= 0 ); + int nToRead = min( (int)(m_DataLen - m_iCurPos), size ); + + if ( m_chMode != 't' ) + { + memcpy( pOutput, &m_pData[m_iCurPos], nToRead ); + m_iCurPos += nToRead; + + return nToRead; + } + else + { + int iRead = 0; + const char *pData = m_pData + m_iCurPos; + int len = m_DataLen - m_iCurPos; + + // Perform crlf translation + while ( const char *crlf = ( const char * ) memchr( pData, '\r', len ) ) + { + int canCopy = min( size, crlf - pData ); + memcpy( pOutput, pData, canCopy ); + + m_iCurPos += canCopy; + pData += canCopy; + len -= canCopy; + + iRead += canCopy; + ( char * & ) pOutput += canCopy; + size -= canCopy; + + if ( size && len ) + { + if ( ( len > 1 ) && ( pData[1] == '\n' ) ) + { + ++ m_iCurPos; + ++ pData; + -- len; + } + + * ( char * & ) pOutput = *pData; + + ++ m_iCurPos; + ++ pData; + -- len; + + ++ iRead; + ++ ( char * & ) pOutput; + -- size; + } + else + break; + } + + if ( size && len ) + { + // No crlf characters left + int canCopy = min( size, len ); + memcpy( pOutput, pData, canCopy ); + + m_iCurPos += canCopy; + pData += canCopy; + len -= canCopy; + + iRead += canCopy; + ( char * & ) pOutput += canCopy; + size -= canCopy; + } + + return iRead; + } +} + +int CVMPIFile_Memory::Write( void const* pInput, int size ) +{ + Assert( false ); return 0; +} + + +// ------------------------------------------------------------------------------------------------------------------------ // +// CBaseVMPIFileSystem implementation. +// ------------------------------------------------------------------------------------------------------------------------ // + +CBaseVMPIFileSystem::~CBaseVMPIFileSystem() +{ +} + + +void CBaseVMPIFileSystem::Release() +{ + delete this; +} + + +void CBaseVMPIFileSystem::Close( FileHandle_t file ) +{ + if ( file ) + ((IVMPIFile*)file)->Close(); +} + +int CBaseVMPIFileSystem::Read( void* pOutput, int size, FileHandle_t file ) +{ + return ((IVMPIFile*)file)->Read( pOutput, size ); +} + +int CBaseVMPIFileSystem::Write( void const* pInput, int size, FileHandle_t file ) +{ + return ((IVMPIFile*)file)->Write( pInput, size ); +} + +void CBaseVMPIFileSystem::Seek( FileHandle_t file, int pos, FileSystemSeek_t seekType ) +{ + ((IVMPIFile*)file)->Seek( pos, seekType ); +} + +unsigned int CBaseVMPIFileSystem::Tell( FileHandle_t file ) +{ + return ((IVMPIFile*)file)->Tell(); +} + +unsigned int CBaseVMPIFileSystem::Size( FileHandle_t file ) +{ + return ((IVMPIFile*)file)->Size(); +} + +unsigned int CBaseVMPIFileSystem::Size( const char *pFilename, const char *pathID = 0 ) +{ + FileHandle_t hFile = Open( pFilename, "rb", NULL ); + if ( hFile == FILESYSTEM_INVALID_HANDLE ) + { + return 0; + } + else + { + unsigned int ret = Size( hFile ); + Close( hFile ); + return ret; + } +} + +bool CBaseVMPIFileSystem::FileExists( const char *pFileName, const char *pPathID ) +{ + FileHandle_t hFile = Open( pFileName, "rb", NULL ); + if ( hFile ) + { + Close( hFile ); + return true; + } + else + { + return false; + } +} + +void CBaseVMPIFileSystem::Flush( FileHandle_t file ) +{ + ((IVMPIFile*)file)->Flush(); +} + +bool CBaseVMPIFileSystem::Precache( const char* pFileName, const char *pPathID ) +{ + return false; +} + + +//----------------------------------------------------------------------------- +// NOTE: This is an exact copy of code in BaseFileSystem.cpp which +// has to be here because they want to call +// the implementation of Open/Size/Read/Write in CBaseVMPIFileSystem +//----------------------------------------------------------------------------- +bool CBaseVMPIFileSystem::ReadFile( const char *pFileName, const char *pPath, CUtlBuffer &buf, int nMaxBytes, int nStartingByte, FSAllocFunc_t pfnAlloc ) +{ + const char *pReadFlags = "rb"; + if ( buf.IsText() && !buf.ContainsCRLF() ) + { + pReadFlags = "rt"; + } + + FileHandle_t fp = Open( pFileName, buf.IsText() ? "rt" : "rb", pPath ); + if ( !fp ) + return false; + + int nBytesToRead = Size( fp ); + if ( nMaxBytes > 0 ) + { + nBytesToRead = min( nMaxBytes, nBytesToRead ); + } + buf.EnsureCapacity( nBytesToRead + buf.TellPut() ); + + if ( nStartingByte != 0 ) + { + Seek( fp, nStartingByte, FILESYSTEM_SEEK_HEAD ); + } + + int nBytesRead = Read( buf.PeekPut(), nBytesToRead, fp ); + buf.SeekPut( CUtlBuffer::SEEK_CURRENT, nBytesRead ); + + Close( fp ); + return (nBytesRead != 0); +} + +bool CBaseVMPIFileSystem::WriteFile( const char *pFileName, const char *pPath, CUtlBuffer &buf ) +{ + const char *pWriteFlags = "wb"; + if ( buf.IsText() && !buf.ContainsCRLF() ) + { + pWriteFlags = "wt"; + } + + FileHandle_t fp = Open( pFileName, buf.IsText() ? "wt" : "wb", pPath ); + if ( !fp ) + return false; + + int nBytesWritten = Write( buf.Base(), buf.TellPut(), fp ); + + Close( fp ); + return (nBytesWritten != 0); +} + |