std1.0.0-beta-7 SafeC docs

Source fs/fat.h

View in the repository

// SafeC Standard Library — FAT32 Read-Only Driver
// Freestanding-safe. Uses a BlockDevice for sector reads.
#pragma once
#include <std/fs/block.h>
#include <std/fs/vfs.h>

// Maximum path components parsed
#define FAT_MAX_DEPTH  8
#define FAT_MAX_CLUSTER 4096   // largest supported cluster size in bytes (FatCtx::init rejects bigger)

namespace std {

struct FatBpb {
    unsigned char  oem_name[8];
    unsigned short bytes_per_sector;
    unsigned char  sectors_per_cluster;
    unsigned short reserved_sectors;
    unsigned char  num_fats;
    unsigned short root_entry_count;    // 0 for FAT32
    unsigned short total_sectors_16;
    unsigned char  media;
    unsigned short fat_size_16;         // 0 for FAT32
    unsigned short sectors_per_track;
    unsigned short num_heads;
    unsigned int   hidden_sectors;
    unsigned int   total_sectors_32;
    // FAT32 extended
    unsigned int   fat_size_32;
    unsigned short ext_flags;
    unsigned short fs_version;
    unsigned int   root_cluster;
    unsigned short fs_info;
    unsigned short backup_boot;
};

struct FatCtx {
    struct BlockDevice dev;
    unsigned long  partition_lba;      // LBA of FAT32 partition start
    struct FatBpb  bpb;
    unsigned long  fat_lba;            // LBA of FAT region
    unsigned long  data_lba;           // LBA of first data cluster
    unsigned long  root_cluster;       // cluster of root directory
    unsigned long  bytes_per_cluster;

    // Initialise this context in place from a block device partition
    // starting at `lba` (the device is copied into `dev`).
    // Returns 0 on success.
    int init(&BlockDevice dev, unsigned long lba);

    // Read a cluster into the first bytes_per_cluster bytes of `buf` (-1
    // if it is shorter).
    int read_cluster(unsigned long cluster, []unsigned char buf);

    // Follow FAT chain to find cluster at position `idx` from `start_cluster`.
    unsigned long follow_fat(unsigned long start_cluster, unsigned long idx);

    // ── FsRead (vfs.h): mount with vfs.mount_ro(mountpoint, &ctx) ──────────
    int           open(const &char path, int flags, &VfsNode node_out);
    unsigned long read(unsigned long inode, unsigned long offset, []unsigned char buf);
    generic<T> int readdir(unsigned long inode, fn void(&VfsNode, ?&T) cb, ?&T user);
    int           readdir_raw_(unsigned long inode, fn void(&VfsNode, ?&Erased) cb, ?&Erased user);
};

generic<T>
int FatCtx::readdir(unsigned long inode, fn void(&VfsNode, ?&T) cb, ?&T user) {
    unsafe { return self.readdir_raw_(inode, (fn void(&VfsNode, ?&Erased))cb, (?&Erased)user); }
}

} // namespace std