#include namespace mercury::kernel::storage { bd_result block_device::load_cache_block(uint64_t i) { if (block_cache_i == i) return bd_result::success; bd_result result = read_blocks_no_cache(i, 1, block_cache); if (result != bd_result::success) { block_cache_i = block_count; return result; } block_cache_i = i; return bd_result::success; } bd_result block_device::read_bytes( uint64_t start, uint64_t count, void *into ) { if (start + count > block_size * block_count) return bd_result::out_of_bounds; uint8_t *into_u8 = (uint8_t *)into; if (start % block_size != 0) { uint64_t prefix_len = block_size - start % block_size; bd_result result = load_cache_block(start / block_size); if (result != bd_result::success) return result; for (uint64_t i = 0; i < prefix_len; ++i) into_u8[i] = block_cache[start % block_size + i]; into_u8 += prefix_len; start += prefix_len; count -= prefix_len; } uint64_t postfix_start = ((start + count) / block_size) * block_size; if (postfix_start != start) { bd_result result = read_blocks_no_cache( start / block_size, (postfix_start - start) / block_size, into_u8); if (result != bd_result::success) return result; count -= postfix_start - start; into_u8 += postfix_start - start; start = postfix_start; } if (count != 0) { bd_result result = load_cache_block(start / block_size); if (result != bd_result::success) return result; for (uint64_t i = 0; i < count; ++i) into_u8[i] = block_cache[i]; } return bd_result::success; } }