Esempio n. 1
0
  Buffer FAT::read(const Dirent& ent, uint64_t pos, uint64_t n) const
  {
    // bounds check the read position and length
    auto stapos = std::min(ent.size(), pos);
    auto endpos = std::min(ent.size(), pos + n);
    // new length
    n = endpos - stapos;
    // cluster -> sector + position
    auto sector = stapos / this->sector_size;
    auto nsect = roundup(endpos, sector_size) / sector_size - sector;

    // read @nsect sectors ahead
    buffer_t data = device.read_sync(this->cl_to_sector(ent.block()) + sector, nsect);
    // where to start copying from the device result
    auto internal_ofs = stapos % device.block_size();
    // when the offset is non-zero we aren't on a sector boundary
    if (internal_ofs != 0) {
      data = construct_buffer(data->begin() + internal_ofs, data->begin() + internal_ofs + n);
    }
    else {
      // when not offset all we have to do is resize the buffer down from
      // a sector size multiple to its given length
      data->resize(n);
    }
    return Buffer(no_error, std::move(data));
  }
Esempio n. 2
0
 List FAT::ls(const Dirent& ent) const
 {
   auto ents = std::make_shared<dirvector> ();
   // verify ent is a directory
   if (!ent.is_valid() || !ent.is_dir())
     return { { error_t::E_NOTDIR, ent.name() }, ents };
   // convert cluster to sector
   auto S = this->cl_to_sector(ent.block());
   // read result directory entries into ents
   auto err = int_ls(S, *ents);
   return { err, ents };
 }
Esempio n. 3
0
 void FAT::ls(const Dirent& ent, on_ls_func on_ls) const
 {
   auto dirents = std::make_shared<dirvector> ();
   // verify ent is a directory
   if (!ent.is_valid() || !ent.is_dir()) {
     on_ls( { error_t::E_NOTDIR, ent.name() }, dirents );
     return;
   }
   // convert cluster to sector
   uint32_t S = this->cl_to_sector(ent.block());
   // read result directory entries into ents
   int_ls(S, dirents, on_ls);
 }
Esempio n. 4
0
  void FAT::read(const Dirent& ent, uint64_t pos, uint64_t n, on_read_func callback) const
  {
    // when n=0 roundup() will return an invalid value
    if (n == 0) {
      callback({ error_t::E_IO, "Zero read length" }, nullptr);
      return;
    }
    // bounds check the read position and length
    uint32_t stapos = std::min(ent.size(), pos);
    uint32_t endpos = std::min(ent.size(), pos + n);
    // new length
    n = endpos - stapos;
    // calculate start and length in sectors
    uint32_t sector = stapos / this->sector_size;
    uint32_t nsect = roundup(endpos, sector_size) / sector_size - sector;
    uint32_t internal_ofs = stapos % device.block_size();

    // cluster -> sector + position
    device.read(
      this->cl_to_sector(ent.block()) + sector,
      nsect,
      hw::Block_device::on_read_func::make_packed(
      [n, callback, internal_ofs] (buffer_t data)
      {
        if (!data) {
          // general I/O error occurred
          callback({ error_t::E_IO, "Unable to read file" }, nullptr);
          return;
        }

        // when the offset is non-zero we aren't on a sector boundary
        if (internal_ofs != 0) {
          // so, we need to create new buffer with offset data
          data = construct_buffer(data->begin() + internal_ofs, data->begin() + internal_ofs + n);
        }
        else {
          // when not offset all we have to do is resize the buffer down from
          // a sector size multiple to its given length
          data->resize(n);
        }

        callback(no_error, data);
      })
    );
  }