// -------------------------------------------------------------------------- // // Function // Name: BackupStoreFile::MoveStreamPositionToBlockIndex(IOStream &) // Purpose: Move the file pointer in this stream to just before the block index. // Assumes that the stream is at the beginning, seekable, and // reading from the stream is OK. // Created: 12/1/04 // // -------------------------------------------------------------------------- void BackupStoreFile::MoveStreamPositionToBlockIndex(IOStream &rStream) { // Size of file int64_t fileSize = rStream.BytesLeftToRead(); // Get header file_StreamFormat hdr; // Read the header if(!rStream.ReadFullBuffer(&hdr, sizeof(hdr), 0 /* not interested in bytes read if this fails */, IOStream::TimeOutInfinite)) { // Couldn't read header THROW_EXCEPTION(BackupStoreException, CouldntReadEntireStructureFromStream) } // Check magic number if(ntohl(hdr.mMagicValue) != OBJECTMAGIC_FILE_MAGIC_VALUE_V1 #ifndef BOX_DISABLE_BACKWARDS_COMPATIBILITY_BACKUPSTOREFILE && ntohl(hdr.mMagicValue) != OBJECTMAGIC_FILE_MAGIC_VALUE_V0 #endif ) { THROW_EXCEPTION(BackupStoreException, BadBackupStoreFile) } // Work out where the index is int64_t numBlocks = box_ntoh64(hdr.mNumBlocks); int64_t blockHeaderPosFromEnd = ((numBlocks * sizeof(file_BlockIndexEntry)) + sizeof(file_BlockIndexHeader)); // Sanity check if(blockHeaderPosFromEnd > static_cast<int64_t>(fileSize - sizeof(file_StreamFormat))) { THROW_EXCEPTION(BackupStoreException, BadBackupStoreFile) } // Seek to that position rStream.Seek(0 - blockHeaderPosFromEnd, IOStream::SeekType_End); // Done. Stream now in right position (as long as the file is formatted correctly) }