//----------------------------------------------------------------------------- void CPUTAssetLibrary::AddAsset(const cString &name, void *pAsset, CPUTAssetListEntry **pHead) { // convert string to lowercase cString lowercaseName = name; std::transform(lowercaseName.begin(), lowercaseName.end(), lowercaseName.begin(), ::tolower); // Do we already have one by this name? CPUTAssetListEntry *pTail = *pHead; // TODO: Save explicit tail pointer instead of iterating to find the null. for( CPUTAssetListEntry *pCur=*pHead; NULL!=pCur; pCur=pCur->pNext ) { // Assert that we haven't added one with this name ASSERT( 0 != _wcsicmp( pCur->name.data(), name.data() ), _L("Warning: asset ")+name+_L(" already exists") ); pTail = pCur; } CPUTAssetListEntry **pDest = pTail ? &pTail->pNext : pHead; *pDest = new CPUTAssetListEntry(); (*pDest)->hash = CPUTComputeHash(name); (*pDest)->name = name; (*pDest)->pData = pAsset; (*pDest)->pNext = NULL; // TODO: Our assets are not yet all derived from CPUTRenderNode. // TODO: For now, rely on caller performing the AddRef() as it knows the assets type. ((CPUTRefCount*)pAsset)->AddRef(); }
void cPackFile::addFilterToFileEntry( const cString& filterName, const cString& fileEntryName ) { int filterIndex = -1; // invalid index cFileEntry* pFileEntry = getFileEntry( fileEntryName ); if ( !pFileEntry ) { // fileEntryName to found cFileSystem::log( LF_ERRORS, "File entry \"%s\" not found in \"%s\" pack file\r\n", fileEntryName.data(), m_pathFileName.data() ); return; } if ( !isFilterRegistered( filterName ) ) { if ( !registerFilter( filterName ) ) { cFileSystem::log( LF_ERRORS, "Failed to register filter \"%s\" with pack file \"%s\"\r\n", filterName.data(), m_pathFileName.data() ); return; } } // find filter index cFilterEntry* pFilterEntry = getFirstFilterEntry(); int i = 0; while ( pFilterEntry ) { if ( pFilterEntry->getName() == filterName ) { filterIndex = i; break; } ++i; pFilterEntry = getNextFilterEntry(); } assert_msg( ( filterIndex >= 0 ), "Invalid filter index" ); pFileEntry->addFilter( filterIndex ); }
bool cPackFile::extractFile( cString& fileEntryName, cString* pDestinationDirectory ) { fixSlashes( fileEntryName ); cFileEntry* pFileEntry = getFileEntry( fileEntryName ); if ( !pFileEntry ) { // fileEntryName is not an entry of this pack file cFileSystem::log( LF_ERRORS, "File \"%s\" is not in \"%s\" pack file\r\n", fileEntryName.data(), m_pathFileName.data() ); return false; } if ( !processFileEntryFilters( *pFileEntry ) ) { // failed to process filters on fileEntryName cFileSystem::log( LF_ERRORS, "Failed to process filters on \"%s\" file entry of \"%s\" pack file\r\n", fileEntryName.data(), m_pathFileName.data() ); return false; } if ( pDestinationDirectory ) { fixSlashes( *pDestinationDirectory ); } cString destinationDirectory; if ( pDestinationDirectory ) { destinationDirectory = *pDestinationDirectory + GOOD_SLASH_STRING + fileEntryName; } else { destinationDirectory = fileEntryName; } cString pathFileEntryName = destinationDirectory; cString path = destinationDirectory; stripFileName( path ); if ( !cFileSystem::createPath( path ) ) { // failed to create path for fileEntryName cFileSystem::log( LF_ERRORS, "Failed to create path \"%s\"\r\n", path.data() ); return false; } cFile* pFile = cFileSystem::openFile( pathFileEntryName, FF_HDFILE | FF_WRITEACCESS ); if ( !pFile ) { // failed to open fileEntryName for writing cFileSystem::log( LF_ERRORS, "Failed to open \"%s\" file for writing\r\n", pathFileEntryName.data() ); return false; } const base::byte* pFileData = pFileEntry->getFilteredData(); dword nbBytesWritten = 0; pFile->write( pFileData, pFileEntry->getFileDataSize(), &nbBytesWritten ); cFileSystem::releaseFile( pFile ); cFileSystem::log( LF_HIGHLIGHTS, "File \"%s\" extracted!\r\n", pathFileEntryName.data() ); return true; }
bool cPackFile::processFileEntryFilters( const cString& fileEntryName ) { cFileEntry* pFileEntry = getFileEntry( fileEntryName ); if ( !pFileEntry ) { // file entry not found! cFileSystem::log( LF_ERRORS, "File entry \"%s\" not found in \"%s\" pack file\r\n", fileEntryName.data(), m_pathFileName.data() ); return false; } return processFileEntryFilters( *pFileEntry ); }
//----------------------------------------------------------------------------- void CPUTAssetLibrary::AddAsset( const cString &name, const cString &prefixDecoration, const cString &suffixDecoration, void *pAsset, CPUTAssetListEntry **pHead, CPUTAssetListEntry **pTail, const char **pShaderMacros, const CPUTModel *pModel, int meshIndex ){ // convert string to lowercase cString lowercaseName = name; std::transform(lowercaseName.begin(), lowercaseName.end(), lowercaseName.begin(), tolow); #ifdef DEBUG // Do we already have one by this name? for( CPUTAssetListEntry *pCur=*pHead; NULL!=pCur; pCur=pCur->pNext ) { // Assert that we haven't added one with this name ASSERT( !((0 == _wcsicmp( pCur->name.data(), name.data() )) && (pCur->pModel == pModel) && (pCur->meshIndex == meshIndex) ), _L("Warning: asset ")+name+_L(" already exists") ); } #endif cString fileName; //FIXME string #ifdef UNICODE cString::size_type index = lowercaseName.rfind(L"/"); if (index == cString::npos) { index = lowercaseName.rfind(L"\\"); } if (index != cString::npos) { fileName = lowercaseName.substr(index + 1); // add one to skip the forward or backward slash } #endif CPUTAssetListEntry **pNext = *pTail ? &(*pTail)->pNext : pHead; *pTail = new CPUTAssetListEntry(); // TODO: init via constructor if(!*pNext ) *pNext = *pTail; (*pTail)->hash = CPUTComputeHash(prefixDecoration + name + suffixDecoration); (*pTail)->name = prefixDecoration + name + suffixDecoration; (*pTail)->pData = pAsset; (*pTail)->pModel = pModel; (*pTail)->meshIndex = meshIndex; (*pTail)->pNext = NULL; (*pTail)->fileName = fileName; // Copy the shader macros. If two assets (shaders only?) have different macros, then they're different assets. // Fix me: add support for shader macros char **p1=(char**)pShaderMacros; int count = 0; if( p1 ) { // Count the macros while( *p1 ) { ++count; ++p1; } (*pTail)->pShaderMacros = new char *[count+2]; // Add 2 for NULL terminator (1 for macro's name and 1 for its value) p1 = (char**)pShaderMacros; char **p2 = (*pTail)->pShaderMacros; while( *p1 && *p2 ) { size_t len = strlen(*p1); *p2 = new char[len+1]; // +1 for NULL terminator #ifdef CPUT_OS_WINDOWS strncpy_s( *p2, len+1, *p1, len+1 ); #else strcpy(*p2, *p1); #endif ++p1; ++p2; } // Set the macro's name and value to NULL *(p2++) = NULL; *p2 = NULL; } else { (*pTail)->pShaderMacros = NULL; } pTail = &(*pTail)->pNext; // TODO: Our assets are not yet all derived from CPUTRenderNode. // TODO: For now, rely on caller performing the AddRef() as it knows the assets type. ((CPUTRefCount*)pAsset)->AddRef(); }