aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sqfs/dir_reader.h52
-rw-r--r--include/sqfs/predef.h1
-rw-r--r--lib/sqfs/src/dir_reader.c52
3 files changed, 76 insertions, 29 deletions
diff --git a/include/sqfs/dir_reader.h b/include/sqfs/dir_reader.h
index abd49bd..eb90b7a 100644
--- a/include/sqfs/dir_reader.h
+++ b/include/sqfs/dir_reader.h
@@ -21,6 +21,7 @@
#define SQFS_DIR_READER_H
#include "sqfs/predef.h"
+#include "sqfs/meta_reader.h"
/**
* @file dir_reader.h
@@ -97,6 +98,57 @@ typedef enum {
SQFS_DIR_OPEN_ALL_FLAGS = 0x00000001,
} SQFS_DIR_OPEN_FLAGS;
+/**
+ * @brief sqfs_dir_reader_state_t
+ *
+ * @extends sqfs_readdir_state_t
+ *
+ * A meta data cursor for reading a directory, but with additional data
+ * for the @ref sqfs_dir_reader_t, e.g. for resolving inodes.
+ */
+struct sqfs_dir_reader_state_t {
+ /**
+ * @brief Base cursor structure for the directory meta data
+ */
+ sqfs_readdir_state_t cursor;
+
+ /**
+ * @brief An inode reference to the parent inode of the directory
+ *
+ * This is only available if the reader was created with
+ * the @ref SQFS_DIR_READER_DOT_ENTRIES flag and the behavior was
+ * not disabled when opening the directory.
+ */
+ sqfs_u64 parent_ref;
+
+ /**
+ * @brief A reference to the inode of the directory itself
+ *
+ * This is only available if the reader was created with
+ * the @ref SQFS_DIR_READER_DOT_ENTRIES flag and the behavior was
+ * not disabled when opening the directory.
+ */
+ sqfs_u64 cur_ref;
+
+ /**
+ * @brief A reference to the current entries inode
+ *
+ * After a successfull call to @ref sqfs_dir_reader_read, this contains
+ * a reference to the inode coresponding to the returned entry.
+ */
+ sqfs_u64 ent_ref;
+
+ /**
+ * @brief An opaque, internal state value
+ */
+ sqfs_u8 state;
+
+ /**
+ * @brief A backup of `state` to reset the state if requested
+ */
+ sqfs_u8 start_state;
+};
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/include/sqfs/predef.h b/include/sqfs/predef.h
index fbc6519..8e7c1b8 100644
--- a/include/sqfs/predef.h
+++ b/include/sqfs/predef.h
@@ -80,6 +80,7 @@ typedef struct sqfs_compressor_config_t sqfs_compressor_config_t;
typedef struct sqfs_compressor_t sqfs_compressor_t;
typedef struct sqfs_dir_writer_t sqfs_dir_writer_t;
typedef struct sqfs_dir_reader_t sqfs_dir_reader_t;
+typedef struct sqfs_dir_reader_state_t sqfs_dir_reader_state_t;
typedef struct sqfs_id_table_t sqfs_id_table_t;
typedef struct sqfs_meta_reader_t sqfs_meta_reader_t;
typedef struct sqfs_meta_writer_t sqfs_meta_writer_t;
diff --git a/lib/sqfs/src/dir_reader.c b/lib/sqfs/src/dir_reader.c
index c44198e..ce93795 100644
--- a/lib/sqfs/src/dir_reader.c
+++ b/lib/sqfs/src/dir_reader.c
@@ -33,16 +33,11 @@ struct sqfs_dir_reader_t {
sqfs_meta_reader_t *meta_inode;
sqfs_super_t super;
- sqfs_readdir_state_t it;
-
sqfs_u32 flags;
- int start_state;
- int state;
- sqfs_u64 parent_ref;
- sqfs_u64 cur_ref;
- sqfs_u64 ent_ref;
rbtree_t dcache;
+
+ sqfs_dir_reader_state_t state;
};
static int inode_copy(const sqfs_inode_generic_t *inode,
@@ -192,7 +187,6 @@ sqfs_dir_reader_t *sqfs_dir_reader_create(const sqfs_super_t *super,
rd->super = *super;
rd->flags = flags;
- rd->state = DIR_STATE_NONE;
return rd;
fail_mdir:
sqfs_drop(rd->meta_inode);
@@ -214,7 +208,7 @@ int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd,
if (flags & (~SQFS_DIR_OPEN_ALL_FLAGS))
return SQFS_ERROR_UNSUPPORTED;
- ret = sqfs_readdir_state_init(&rd->it, &rd->super, inode);
+ ret = sqfs_readdir_state_init(&rd->state.cursor, &rd->super, inode);
if (ret)
return ret;
@@ -226,21 +220,21 @@ int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd,
parent = inode->data.dir.parent_inode;
}
- if (dcache_find(rd, inode->base.inode_number, &rd->cur_ref))
+ if (dcache_find(rd, inode->base.inode_number, &rd->state.cur_ref))
return SQFS_ERROR_NO_ENTRY;
- if (rd->cur_ref == rd->super.root_inode_ref) {
- rd->parent_ref = rd->cur_ref;
- } else if (dcache_find(rd, parent, &rd->parent_ref)) {
+ if (rd->state.cur_ref == rd->super.root_inode_ref) {
+ rd->state.parent_ref = rd->state.cur_ref;
+ } else if (dcache_find(rd, parent, &rd->state.parent_ref)) {
return SQFS_ERROR_NO_ENTRY;
}
- rd->state = DIR_STATE_OPENED;
+ rd->state.state = DIR_STATE_OPENED;
} else {
- rd->state = DIR_STATE_ENTRIES;
+ rd->state.state = DIR_STATE_ENTRIES;
}
- rd->start_state = rd->state;
+ rd->state.start_state = rd->state.state;
return 0;
}
@@ -266,19 +260,19 @@ int sqfs_dir_reader_read(sqfs_dir_reader_t *rd, sqfs_dir_node_t **out)
{
int err;
- switch (rd->state) {
+ switch (rd->state.state) {
case DIR_STATE_OPENED:
err = mk_dummy_entry(".", out);
if (err == 0) {
- rd->state = DIR_STATE_DOT;
- rd->ent_ref = rd->cur_ref;
+ rd->state.state = DIR_STATE_DOT;
+ rd->state.ent_ref = rd->state.cur_ref;
}
return err;
case DIR_STATE_DOT:
err = mk_dummy_entry("..", out);
if (err == 0) {
- rd->state = DIR_STATE_ENTRIES;
- rd->ent_ref = rd->parent_ref;
+ rd->state.state = DIR_STATE_ENTRIES;
+ rd->state.ent_ref = rd->state.parent_ref;
}
return err;
case DIR_STATE_ENTRIES:
@@ -287,17 +281,17 @@ int sqfs_dir_reader_read(sqfs_dir_reader_t *rd, sqfs_dir_node_t **out)
return SQFS_ERROR_SEQUENCE;
}
- return sqfs_meta_reader_readdir(rd->meta_dir, &rd->it,
- out, NULL, &rd->ent_ref);
+ return sqfs_meta_reader_readdir(rd->meta_dir, &rd->state.cursor,
+ out, NULL, &rd->state.ent_ref);
}
int sqfs_dir_reader_rewind(sqfs_dir_reader_t *rd)
{
- if (rd->state == DIR_STATE_NONE)
+ if (rd->state.state == DIR_STATE_NONE)
return SQFS_ERROR_SEQUENCE;
- sqfs_readdir_state_reset(&rd->it);
- rd->state = rd->start_state;
+ sqfs_readdir_state_reset(&rd->state.cursor);
+ rd->state.state = rd->state.start_state;
return 0;
}
@@ -307,12 +301,12 @@ int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd,
int ret;
ret = sqfs_meta_reader_read_inode(rd->meta_inode, &rd->super,
- rd->ent_ref >> 16,
- rd->ent_ref & 0x0FFFF, inode);
+ rd->state.ent_ref >> 16,
+ rd->state.ent_ref & 0x0FFFF, inode);
if (ret != 0)
return ret;
- return dcache_add(rd, *inode, rd->ent_ref);
+ return dcache_add(rd, *inode, rd->state.ent_ref);
}
int sqfs_dir_reader_get_root_inode(sqfs_dir_reader_t *rd,