Gottox / sqsh-tools

🗜️ fast r/o squashfs implementation written in C.
https://gottox.de/sqsh-tools/
BSD 2-Clause "Simplified" License
38 stars 4 forks source link

Make `sqsh_tree_walker_up` position the walker at the entry of the previous directory #124

Closed Dr-Emann closed 1 year ago

Dr-Emann commented 1 year ago

Is your feature request related to a problem? Please describe.

I want to be able to use a walker to navigate to every file in the archive, recursively.

I'd like to use something like:

Code Example ```c void visit_all_entries(struct SqshTreeWalker *walker) { int rc = 0; while (sqsh_tree_walker_next2(walker, &rc)) { char *name = sqsh_tree_walker_name_dup(walker); printf("Visiting %s\n", name); free(name); if (sqsh_tree_walker_type(walker) == SQSH_FILE_TYPE_DIRECTORY) { printf("BEGIN DIR\n"); rc = sqsh_tree_walker_down(walker); assert(rc == 0); visit_all_entries(walker); rc = sqsh_tree_walker_up(walker); assert(rc == 0); printf("END DIR\n"); } } assert(rc == 0); } ```

However, this doesn't work, because sqsh_tree_walker_up sets the walker to be at the start of the parent directory, not at the entry of the inner directory it was just in.

I'm not sure if such a thing is possible to do efficiently.

Describe the solution you'd like

Ideally, it would be better to have sqsh_tree_walker_up would return to the entry of the directory just left rather than the beginning of the parent directory.

Describe alternatives you've considered

It is probably possible to save the name, and use sqsh_tree_walker_lookup to get back to the directory. But presumably that will inefficient.

Alternatively, it might require keeping our own stack of SqshDirectoryIterators to do such visitation of files.

Additional context

Gottox commented 1 year ago

There are two reasons why the tree_walker resets the directory iterator to the start:

There's also this issue: What happens if the tree_walker isn't initialized for the root directory, but for a random other directory. I don't support that through the API yet, but it's a use case that I'm considering to expose. In that case we would need to...

  1. ...check if this directory was already visited by this walker and
  2. ...if it wasn't visited do a linear search through the parent directory every time we call _up() to find the right directory entry anyway.

I think you're trying to use tree_walker for something that it wasn't made for. To recursively visit every file in an archive, I would suggest use a recursive function in conjuction with directory iterators instead. As an example, you can have a look at sqsh-unpacks extract() function which does exactly that..

Dr-Emann commented 1 year ago

I'm sure I am just trying to use it wrong. I think the name confused me, I associated it with something like WalkDir, that it would be the way to walk the whole tree. It seems like it's probably closer to an internal tool for path resolution, than something I'd want to really use as a caller of the library.