// DatLibrary.cpp : Implementation of cDatLibrary #include "stdafx.h" #include "DecalDat.h" #include "DatLibrary.h" #include "DatFile.h" #include "DatService.h" #include "DatStream.h" ///////////////////////////////////////////////////////////////////////////// // cDatLibrary void cDatLibrary::load( cDatService *pService, BSTR strFilename, int nFileType, long nSectorSize ) { USES_CONVERSION; // Convert the template path into a real path m_pService = pService; CComBSTR strPath; pService->m_pDecal->MapPath( strFilename, &strPath ); m_nFileType = nFileType; try { m_pFile = new cDatFile( OLE2T( strPath ), nSectorSize ); } catch( ... ) { } } HRESULT cDatLibrary::createFile( DWORD dwFile, REFIID iid, void **ppvItf ) { CComObject< cDatStream > *pStream; CComObject< cDatStream >::CreateInstance( &pStream ); CComPtr< IUnknown > pUnkStream = pStream; try { pStream->m_pFile = new cDatFile::cFile( m_pFile->getFile( dwFile ) ); } catch( ... ) { delete pStream; // File not found return E_INVALIDARG; } return pStream->QueryInterface( iid, ppvItf ); } STDMETHODIMP cDatLibrary::Lookup( BSTR strName, IUnknown **ppItf ) { USES_CONVERSION; LPTSTR szName = OLE2T( strName ); int nProtocol = ::_tcscspn( szName, _T( ":" ) ); if( szName[ nProtocol ] == _T( '\0' ) ) { // Special case, no protocol creates a raw stream DWORD dwFile; if( ::_stscanf( szName, _T( "%X" ), &dwFile ) != 1 ) return E_INVALIDARG; return get_Stream( dwFile, ppItf ); } // We have a protocol name szName[ nProtocol ] = _T( '\0' ); // Convert the hew file number DWORD dwFile; if( ::_stscanf( szName + nProtocol + 1, _T( "%X" ), &dwFile ) != 1 ) { _ASSERT( FALSE ); return E_INVALIDARG; } return Open( CComBSTR( szName ), dwFile, ppItf ); } STDMETHODIMP cDatLibrary::get_Stream(DWORD dwFile, LPUNKNOWN *pVal) { return createFile( dwFile, IID_IUnknown, reinterpret_cast< void ** >( pVal ) ); } STDMETHODIMP cDatLibrary::Open(BSTR Protocol, DWORD File, LPUNKNOWN *pFile) { USES_CONVERSION; LPTSTR szName = OLE2T( Protocol ); ::_tcslwr( szName ); cDatService::cFileFilter *pFilter = m_pService->getFilter( szName, ::_tcslen( szName ) ); if( pFilter == NULL ) { _ASSERT( FALSE ); return E_INVALIDARG; } if( pFilter->m_bCache ) { // Check the file cache for an existing verison for( cDatService::cFileCacheList::iterator i = m_pService->m_cache.begin(); i != m_pService->m_cache.end(); ++ i ) { if( i->m_dwFile == File && static_cast< int >( i->m_library ) == m_nFileType && i->m_pFilter == pFilter ) { // Found our file, return victorious return i->m_pFile->QueryInterface( pFile ); } } } // No cache or not found in the cache, create the stream CComPtr< IDatStream > pStream; HRESULT hRes = createFile( File, IID_IDatStream, reinterpret_cast< void ** >( &pStream ) ); if( FAILED( hRes ) ) { _ASSERT( FALSE ); return hRes; } // Lookin' good, create the filter CComPtr< IFileFilter > pFileFilter; hRes = m_pService->createFilter( pFilter, IID_IFileFilter, reinterpret_cast< void ** >( &pFileFilter ) ); if( FAILED( hRes ) ) { _ASSERT( FALSE ); return hRes; } hRes = pFileFilter->Initialize( pStream ); if( FAILED( hRes ) ) { _ASSERT( FALSE ); return hRes; } if( pFilter->m_bCache ) { // Make a cache entry cDatService::cFileCache fc; fc.m_dwFile = File; fc.m_library = static_cast< cDatService::eLibrary >( m_nFileType ); fc.m_pFilter = pFilter; fc.m_pFile = pFileFilter; m_pService->m_cache.push_back( fc ); } return pFileFilter->QueryInterface( IID_IUnknown, reinterpret_cast< void ** >( pFile ) ); }