1 /* 2 * Copyright (c) 2022 Travis Geiselbrecht 3 * 4 * Use of this source code is governed by a MIT-style 5 * license that can be found in the LICENSE file or at 6 * https://opensource.org/licenses/MIT 7 */ 8 #pragma once 9 10 #include <lib/bio.h> 11 #include <lk/cpp.h> 12 #include <lk/debug.h> 13 #include <stdint.h> 14 #include <sys/types.h> 15 16 #include "fat_fs.h" 17 18 // Local object used to track the state of walking through a file or directory 19 // one sector at a time using the block cache. Holds a reference to the open 20 // block cache block and intelligently returns and gets the next one when necessary. 21 class file_block_iterator { 22 public: 23 // initialize with the starting cluster of the file or directory. 24 // special case of starting_cluster == 0 will cause it to track 25 // the root directory of a fat 12 or 16 volume, which handle 26 // root directories differently. 27 file_block_iterator(fat_fs *_fat, uint32_t starting_cluster); 28 ~file_block_iterator(); 29 30 DISALLOW_COPY_ASSIGN_AND_MOVE(file_block_iterator); 31 get_bcache_ptr(size_t offset)32 const uint8_t *get_bcache_ptr(size_t offset) { 33 DEBUG_ASSERT(offset < fat->info().bytes_per_sector); 34 DEBUG_ASSERT(bcache_buf); 35 return (const uint8_t *)bcache_buf + offset; 36 } 37 38 // move N sectors ahead in the file, walking the FAT cluster chain as necessary. 39 // sectors == 0 will ensure the current block is loaded. 40 status_t next_sectors(uint32_t sectors); 41 42 // move one sector next_sector()43 status_t next_sector() { return next_sectors(1); } 44 45 // return the number of sectors this has moved forward during its lifetime get_sector_inc_count()46 uint32_t get_sector_inc_count() const { return sector_inc_count; } reset_sector_inc_count()47 void reset_sector_inc_count() { sector_inc_count = 0; } 48 49 private: 50 void put_bcache_block(); 51 status_t load_current_bcache_block(); 52 status_t load_bcache_block(bnum_t bnum); 53 54 fat_fs *fat; 55 uint32_t cluster; // current cluster we're on 56 uint32_t sector_offset; // sector number within cluster 57 uint32_t sector_inc_count = 0; // number of sectors we have moved forward in the lifetime of this 58 59 void *bcache_buf = nullptr; // current pointer to the bcache, if held 60 bnum_t bcache_bnum; // current block number of the bcache_buf, if valid 61 }; 62 63