summaryrefslogtreecommitdiff
path: root/utils/vmpi/vmpi_filesystem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/vmpi/vmpi_filesystem.cpp')
-rw-r--r--utils/vmpi/vmpi_filesystem.cpp366
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);
+}
+