bool SectorReader::Read(u64 offset, u64 size, u8* out_ptr) { u64 remain = size; u64 block = 0; u32 position_in_block = static_cast<u32>(offset % m_block_size); while (remain > 0) { block = offset / m_block_size; const Cache* cache = GetCacheLine(block); if (!cache) return false; // Cache entries are aligned chunks, we may not want to read from the start u32 read_offset = static_cast<u32>(block - cache->block_idx) * m_block_size + position_in_block; u32 can_read = m_block_size * cache->num_blocks - read_offset; u32 was_read = static_cast<u32>(std::min<u64>(can_read, remain)); std::copy(cache->data.begin() + read_offset, cache->data.begin() + read_offset + was_read, out_ptr); offset += was_read; out_ptr += was_read; remain -= was_read; position_in_block = 0; } return true; }
///////////////////////////////////////////////////////// // Description: // flush content in IOBuffer to real hardware storage // // Input: // // // output: // // // Remarks: // // Returns: void FAT_SectorCache::FlushSector( UINT32 sectorIndex ) { FAT_CacheLine* cacheLine = GetCacheLine( sectorIndex ); if(cacheLine) { FlushSector( cacheLine ); } }
void FAT_SectorCache::MarkSectorDirty( UINT32 sectorIndex ) { FAT_CacheLine* cacheLine = GetCacheLine( sectorIndex ); if(cacheLine) { cacheLine->SetDirty( TRUE ); } }
BYTE* FAT_SectorCache::GetSector( UINT32 sectorIndex, BOOL forWrite ) { if(sectorIndex > m_sectorCount) //sectorIndex out of range of this device return NULL; FAT_CacheLine* cacheLine = GetCacheLine( sectorIndex ); if(!cacheLine) { cacheLine = GetUnusedCacheLine(); if(!cacheLine->m_buffer) { cacheLine->m_buffer = (BYTE*)private_malloc( SECTORCACHE_LINESIZE ); if(!cacheLine->m_buffer) return NULL; } cacheLine->m_begin = sectorIndex - (sectorIndex % m_sectorsPerLine); cacheLine->m_bsByteAddress = m_baseByteAddress + cacheLine->m_begin * m_bytesPerSector; cacheLine->m_flags = 0; if(!m_blockStorageDevice->Read( cacheLine->m_bsByteAddress, SECTORCACHE_LINESIZE, cacheLine->m_buffer )) { private_free( cacheLine->m_buffer ); cacheLine->m_buffer = NULL; return NULL; } } if(forWrite) cacheLine->SetDirty( TRUE ); if((cacheLine->GetLRUCounter()) != m_LRUCounter) { m_LRUCounter++; cacheLine->SetLRUCOunter( m_LRUCounter ); } return cacheLine->m_buffer + (sectorIndex - cacheLine->m_begin) * m_bytesPerSector; }