//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ // //=============================================================================// #include "filememcache.h" namespace { unsigned long s_ulCachedFileSignature = 0xCACEF11E; }; // // Cached file data implementation // CachedFileData * CachedFileData::Create( char const *szFilename ) { FILE *f = fopen( szFilename, "rb" ); int nSize = -1; if ( f ) { fseek( f, 0, SEEK_END ); nSize = ftell( f ); fseek( f, 0, SEEK_SET ); } CachedFileData *pData = ( CachedFileData * ) malloc( eHeaderSize + max( nSize, 0 ) ); strcpy( pData->m_chFilename, szFilename ); pData->m_numRefs = 0; pData->m_numDataBytes = nSize; pData->m_signature = s_ulCachedFileSignature; if ( f ) { fread( pData->m_data, 1, nSize, f ); fclose( f ); } return pData; } void CachedFileData::Free( void ) { free( this ); } CachedFileData *CachedFileData::GetByDataPtr( void const *pvDataPtr ) { unsigned char const *pbBuffer = reinterpret_cast< unsigned char const * >( pvDataPtr ); // Assert( pbBuffer ); CachedFileData const *pData = reinterpret_cast< CachedFileData const * >( pbBuffer - eHeaderSize ); // Assert( pData->m_signature == s_ulCachedFileSignature ); return const_cast< CachedFileData * >( pData ); } char const * CachedFileData::GetFileName() const { return m_chFilename; } void const * CachedFileData::GetDataPtr() const { return m_data; } int CachedFileData::GetDataLen() const { return max( m_numDataBytes, 0 ); } bool CachedFileData::IsValid() const { return ( m_numDataBytes >= 0 ); } // // File cache implementation // FileCache::FileCache() { NULL; } CachedFileData * FileCache::Get( char const *szFilename ) { // Search the cache first Mapping::iterator it = m_map.find( szFilename ); if ( it != m_map.end() ) return it->second; // Create the cached file data CachedFileData *pData = CachedFileData::Create( szFilename ); if ( pData ) m_map.insert( Mapping::value_type( pData->GetFileName(), pData ) ); return pData; } void FileCache::Clear() { for ( Mapping::iterator it = m_map.begin(), itEnd = m_map.end(); it != itEnd; ++ it ) { it->second->Free(); } m_map.clear(); }