XBOX::VFile *VXMLParser::ResolveEntityFromFolder( const VString& inEntityBase, VFolder *inEntityLocalFolder, const VString& inSystemID) { VFile *file = NULL; if (inEntityLocalFolder != NULL) { if (inSystemID.BeginsWith( inEntityBase)) { VString relativePath = inSystemID; relativePath.Exchange( inEntityBase, CVSTR( "")); // convert into native path to please VFile for( UniChar *p = relativePath.GetCPointerForWrite() ; *p ; ++p) { if (*p == '/') *p = FOLDER_SEPARATOR; } VFilePath path( inEntityLocalFolder->GetPath(), relativePath); if (path.IsFile()) file = new VFile( path); } } return file; }
VError VArchiveUnStream::ProceedCatalog() { VError result = VE_OK; VStr8 dotSlash("./"); VStr8 slash("/"); VStr8 extra("::"); VStr8 folderSep(XBOX::FOLDER_SEPARATOR); if ( fStream->GetLong() == 'FPBK' ) { VString filePath; VString fileExtra; VString storedPath; uLONG kind = 0; uLONG creator = 0; sLONG8 dataFileSize = 0; sLONG8 resFileSize = 0; uBYTE version = fStream->GetByte(); uLONG8 fileCount = fStream->GetLong8(); fTotalByteCount = 0; if ( fStream->GetLong() == 'LIST' ) { for ( uLONG i = 0; i < fileCount && result == VE_OK; i++ ) { if ( fStream->GetLong() == 'file' ) { result = filePath.ReadFromStream(fStream); if ( result == VE_OK ) { VIndex index = filePath.Find(extra); fileExtra = filePath; fileExtra.Remove(1,index+1); filePath.Remove(index,filePath.GetLength()-index+1); storedPath = filePath; if ( filePath.Find( dotSlash ) > 0 ) { // some archives have bogous file paths such as ./Z:/folder filePath.Exchange( (UniChar) ':', (UniChar) '_'); filePath.Replace(fDestinationFolder.GetPath(),1,2); } filePath.Exchange(slash ,folderSep, 1, 255); dataFileSize = fStream->GetLong8(); fTotalByteCount += dataFileSize; resFileSize = fStream->GetLong8(); fTotalByteCount += resFileSize; kind = fStream->GetLong(); creator = fStream->GetLong(); VFile *file = new VFile(filePath); fFileCatalog.push_back(new VArchiveCatalog(file,dataFileSize,resFileSize,storedPath,fileExtra,kind,creator)); ReleaseRefCountable( &file); } } else result = VE_STREAM_BAD_SIGNATURE; } } else result = VE_STREAM_BAD_SIGNATURE; } return result; }
//ACI0078887 23rd Nov 2012, O.R., always specify folder used for computing relative path of entry in TOC VError VArchiveStream::_WriteCatalog( const VFile* inFile, const XBOX::VFilePath& inSourceFolder,const VString &inExtraInfo, uLONG8 &ioTotalByteCount ) { VString fileInfo; VStr8 slash("/"); VStr8 extra("::"); VStr8 folderSep(XBOX::FOLDER_SEPARATOR); VError result = VE_INVALID_PARAMETER; XBOX::VString savedExtraInfo = inExtraInfo; //ACI0078887 23rd Nov 2012, O.R., compute relative path using the specified source folder //don't assume that extra info carries relative folder info //ACI0078887 23rd Nov 2012, O.R., compute relative path using the specified source folder //don't assume that extra info carries relative folder info if (savedExtraInfo == PRESERVE_PARENT_OPTION) { //this is a bogus extra info that we use internally so we need to clear it so that it is not saved into //the archive. //This options means that the file will have to be restored in with its parent directory preserved. savedExtraInfo.Clear(); VFolder *folder = inFile->RetainParentFolder(); VString fileName; folder->GetName(fileInfo); // folder name can be a drive letter like Z: fileInfo.Exchange( (UniChar) ':', (UniChar) '_'); inFile->GetName(fileName); fileInfo += slash; fileInfo += fileName; fileInfo.Insert( slash, 1 ); folder->Release(); result = VE_OK; } else { if(testAssert(inFile->GetPath().GetRelativePath(inSourceFolder,fileInfo))) { result = VE_OK; fileInfo.Insert( FOLDER_SEPARATOR, 1); } } if(result == VE_OK) { fileInfo.Exchange(folderSep ,slash, 1, 255); if ( fileInfo.GetUniChar(1) == '/' ) fileInfo.Insert( '.', 1 ); fileInfo += extra; fileInfo += savedExtraInfo; result = fStream->PutLong('file'); if ( result == VE_OK ) { result = fileInfo.WriteToStream(fStream); } if ( result == VE_OK ) { sLONG8 fileSize = 0; inFile->GetSize(&fileSize); fStream->PutLong8(fileSize); ioTotalByteCount += fileSize; #if VERSIONWIN || VERSION_LINUX /* rez file size */ fStream->PutLong8(0); /* no file kind or creator under Windows */ fStream->PutLong(0); /* kind */ fStream->PutLong(0); /* creator */ #elif VERSIONMAC inFile->GetResourceForkSize(&fileSize); fStream->PutLong8(fileSize); ioTotalByteCount += fileSize; OsType osType; inFile->MAC_GetKind( &osType ); result = fStream->PutLong( osType ); inFile->MAC_GetCreator( &osType ); result = fStream->PutLong( osType ); #endif } } return result; }