示例#1
0
  error_t FAT::traverse(Path path, dirvector& ents, const Dirent* const start) const
  {
    // start with given entry (defaults to root)
    uint32_t cluster = start ? start->block() : 0;
    Dirent found(this, INVALID_ENTITY);

    while (!path.empty()) {

      auto S = this->cl_to_sector(cluster);
      ents.clear(); // mui importante
      // sync read entire directory
      auto err = int_ls(S, ents);
      if (UNLIKELY(err)) return err;
      // the name we are looking for
      const std::string name = path.front();
      path.pop_front();

      // check for matches in dirents
      for (auto& e : ents)
      if (UNLIKELY(e.name() == name)) {
        // go to this directory, unless its the last name
        FS_PRINT("traverse_sync: Found match for %s", name.c_str());
        // enter the matching directory
        FS_PRINT("\t\t cluster: %lu\n", e.block());
        // only follow if the name is a directory
        if (e.type() == DIR) {
          found = e;
          break;
        }
        else {
          // not dir = error, for now
          return { error_t::E_NOTDIR, "Cannot list non-directory" };
        }
      } // for (ents)

      // validate result
      if (found.type() == INVALID_ENTITY) {
        FS_PRINT("traverse_sync: NO MATCH for %s\n", name.c_str());
        return { error_t::E_NOENT, name };
      }
      // set next cluster
      cluster = found.block();
    }

    auto S = this->cl_to_sector(cluster);
    // read result directory entries into ents
    ents.clear(); // mui importante!
    return int_ls(S, ents);
  }
示例#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 };
 }
示例#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);
 }
示例#4
0
  void FAT::traverse(std::shared_ptr<Path> path, cluster_func callback)
  {
    // parse this path into a stack of memes
    typedef std::function<void(uint32_t)> next_func_t;

    // asynch stack traversal
    auto next = std::make_shared<next_func_t> ();
    auto weak_next = std::weak_ptr<next_func_t>(next);
    *next =
    [this, path, weak_next, callback] (uint32_t cluster) {

      if (path->empty()) {
        // attempt to read directory
        uint32_t S = this->cl_to_sector(cluster);

        // result allocated on heap
        auto dirents = std::make_shared<std::vector<Dirent>> ();

        int_ls(S, dirents,
        [callback] (error_t error, dirvec_t ents) {
          callback(error, ents);
        });
        return;
      }

      // retrieve next name
      std::string name = path->front();
      path->pop_front();

      uint32_t S = this->cl_to_sector(cluster);
      debug("Current target: %s on cluster %u (sector %u)\n", name.c_str(), cluster, S);

      // result allocated on heap
      auto dirents = std::make_shared<std::vector<Dirent>> ();

      auto next = weak_next.lock();
      // list directory contents
      int_ls(S, dirents,
      [name, dirents, next, callback] (error_t err, dirvec_t ents) {

        if (unlikely(err)) {
          debug("Could not find: %s\n", name.c_str());
          callback(err, dirents);
          return;
        }

        // look for name in directory
        for (auto& e : *ents) {
          if (unlikely(e.name() == name)) {
            // go to this directory, unless its the last name
            debug("Found match for %s", name.c_str());
            // enter the matching directory
            debug("\t\t cluster: %llu\n", e.block);
            // only follow directories
            if (e.type() == DIR)
              (*next)(e.block);
            else
              callback({ error_t::E_NOTDIR, e.name() }, dirents);
            return;
          }
        } // for (ents)

        debug("NO MATCH for %s\n", name.c_str());
        callback({ error_t::E_NOENT, name }, dirents);
      });

    };
    // start by reading root directory
    (*next)(0);
  }