[dovecot-cvs] dovecot/src/lib-storage mailbox-tree.c, 1.4, 1.5 mailbox-tree.h, 1.3, 1.4
tss at dovecot.org
tss at dovecot.org
Wed Apr 11 22:07:18 EEST 2007
Update of /var/lib/cvs/dovecot/src/lib-storage
In directory talvi:/tmp/cvs-serv3571
Modified Files:
mailbox-tree.c mailbox-tree.h
Log Message:
Moved mailbox_tree iteration code from maildir++ to common code, and rewrote
it.
Index: mailbox-tree.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/mailbox-tree.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- mailbox-tree.c 15 Mar 2007 01:25:18 -0000 1.4
+++ mailbox-tree.c 11 Apr 2007 19:07:15 -0000 1.5
@@ -1,6 +1,7 @@
-/* Copyright (C) 2003 Timo Sirainen */
+/* Copyright (C) 2003-2007 Timo Sirainen */
#include "lib.h"
+#include "array.h"
#include "str.h"
#include "mailbox-tree.h"
@@ -10,26 +11,42 @@
struct mailbox_node *nodes;
};
+struct mailbox_tree_iterate_context {
+ struct mailbox_node *root, *next_node;
+ unsigned int flags_mask;
+
+ char separator;
+
+ ARRAY_DEFINE(node_path, struct mailbox_node *);
+ string_t *path_str;
+ size_t parent_pos;
+
+ unsigned int first_child:1;
+};
+
struct mailbox_tree_context *mailbox_tree_init(char separator)
{
- struct mailbox_tree_context *ctx;
+ struct mailbox_tree_context *tree;
pool_t pool;
pool = pool_alloconly_create(MEMPOOL_GROWING"mailbox_tree", 10240);
- ctx = p_new(pool, struct mailbox_tree_context, 1);
- ctx->pool = pool;
- ctx->separator = separator;
- return ctx;
+ tree = p_new(pool, struct mailbox_tree_context, 1);
+ tree->pool = pool;
+ tree->separator = separator;
+ return tree;
}
-void mailbox_tree_deinit(struct mailbox_tree_context *ctx)
+void mailbox_tree_deinit(struct mailbox_tree_context **_tree)
{
- pool_unref(ctx->pool);
+ struct mailbox_tree_context *tree = *_tree;
+
+ *_tree = NULL;
+ pool_unref(tree->pool);
}
static struct mailbox_node *
-mailbox_tree_traverse(struct mailbox_tree_context *ctx, const char *path,
+mailbox_tree_traverse(struct mailbox_tree_context *tree, const char *path,
bool create, bool *created)
{
struct mailbox_node **node;
@@ -40,19 +57,19 @@
*created = FALSE;
if (path == NULL)
- return ctx->nodes;
+ return tree->nodes;
t_push();
if (strncasecmp(path, "INBOX", 5) == 0 &&
- (path[5] == '\0' || path[5] == ctx->separator))
+ (path[5] == '\0' || path[5] == tree->separator))
path = t_strdup_printf("INBOX%s", path+5);
- node = &ctx->nodes;
+ node = &tree->nodes;
str = t_str_new(strlen(path)+1);
for (name = path;; path++) {
- if (*path != ctx->separator && *path != '\0')
+ if (*path != tree->separator && *path != '\0')
continue;
str_truncate(str, 0);
@@ -72,8 +89,8 @@
if (!create)
break;
- *node = p_new(ctx->pool, struct mailbox_node, 1);
- (*node)->name = p_strdup(ctx->pool, name);
+ *node = p_new(tree->pool, struct mailbox_node, 1);
+ (*node)->name = p_strdup(tree->pool, name);
if (*path != '\0') {
(*node)->flags = MAILBOX_NONEXISTENT |
@@ -96,14 +113,107 @@
}
struct mailbox_node *
-mailbox_tree_get(struct mailbox_tree_context *ctx, const char *path,
+mailbox_tree_get(struct mailbox_tree_context *tree, const char *path,
bool *created)
{
- return mailbox_tree_traverse(ctx, path, TRUE, created);
+ return mailbox_tree_traverse(tree, path, TRUE, created);
}
struct mailbox_node *
-mailbox_tree_update(struct mailbox_tree_context *ctx, const char *path)
+mailbox_tree_update(struct mailbox_tree_context *tree, const char *path)
{
- return mailbox_tree_traverse(ctx, path, FALSE, NULL);
+ return mailbox_tree_traverse(tree, path, FALSE, NULL);
+}
+
+struct mailbox_tree_iterate_context *
+mailbox_tree_iterate_init(struct mailbox_tree_context *tree,
+ struct mailbox_node *root, unsigned int flags_mask)
+{
+ struct mailbox_tree_iterate_context *ctx;
+
+ ctx = i_new(struct mailbox_tree_iterate_context, 1);
+ ctx->separator = tree->separator;
+ ctx->root = root != NULL ? root : mailbox_tree_get(tree, NULL, NULL);
+ ctx->flags_mask = flags_mask;
+ ctx->path_str = str_new(default_pool, 256);
+ i_array_init(&ctx->node_path, 16);
+
+ ctx->next_node = ctx->root;
+ return ctx;
+}
+
+static void
+mailbox_tree_iterate_set_next_node(struct mailbox_tree_iterate_context *ctx)
+{
+ struct mailbox_node *node = ctx->next_node;
+ struct mailbox_node *const *nodes;
+ unsigned int i, count;
+
+ if (node->children != NULL) {
+ array_append(&ctx->node_path, &node, 1);
+ ctx->parent_pos = str_len(ctx->path_str);
+ node = node->children;
+ ctx->first_child = TRUE;
+ } else if (node->next != NULL) {
+ node = node->next;
+ } else {
+ nodes = array_get(&ctx->node_path, &count);
+ node = NULL;
+ for (i = count; i != 0; i--) {
+ unsigned int len = strlen(nodes[i-1]->name) + 1;
+
+ i_assert(len <= ctx->parent_pos);
+ ctx->parent_pos -= len;
+ if (nodes[i-1]->next != NULL) {
+ node = nodes[i-1]->next;
+ ctx->first_child = TRUE;
+ i--;
+
+ if (ctx->parent_pos != 0)
+ ctx->parent_pos--;
+ break;
+ }
+ }
+ array_delete(&ctx->node_path, i, count - i);
+ }
+
+ ctx->next_node = node;
+}
+
+struct mailbox_node *
+mailbox_tree_iterate_next(struct mailbox_tree_iterate_context *ctx,
+ const char **path_r)
+{
+ struct mailbox_node *node;
+
+ do {
+ node = ctx->next_node;
+ if (node == NULL)
+ return NULL;
+
+ str_truncate(ctx->path_str, ctx->parent_pos);
+ if (ctx->first_child) {
+ ctx->first_child = FALSE;
+ if (ctx->parent_pos != 0) {
+ str_append_c(ctx->path_str, ctx->separator);
+ ctx->parent_pos++;
+ }
+ }
+ str_append(ctx->path_str, node->name);
+
+ mailbox_tree_iterate_set_next_node(ctx);
+ } while ((node->flags & ctx->flags_mask) != ctx->flags_mask);
+
+ *path_r = str_c(ctx->path_str);
+ return node;
+}
+
+void mailbox_tree_iterate_deinit(struct mailbox_tree_iterate_context **_ctx)
+{
+ struct mailbox_tree_iterate_context *ctx = *_ctx;
+
+ *_ctx = NULL;
+ str_free(&ctx->path_str);
+ array_free(&ctx->node_path);
+ i_free(ctx);
}
Index: mailbox-tree.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/mailbox-tree.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- mailbox-tree.h 16 Nov 2006 00:16:32 -0000 1.3
+++ mailbox-tree.h 11 Apr 2007 19:07:15 -0000 1.4
@@ -12,13 +12,21 @@
};
struct mailbox_tree_context *mailbox_tree_init(char separator);
-void mailbox_tree_deinit(struct mailbox_tree_context *ctx);
+void mailbox_tree_deinit(struct mailbox_tree_context **tree);
struct mailbox_node *
-mailbox_tree_get(struct mailbox_tree_context *ctx, const char *path,
+mailbox_tree_get(struct mailbox_tree_context *tree, const char *path,
bool *created);
struct mailbox_node *
-mailbox_tree_update(struct mailbox_tree_context *ctx, const char *path);
+mailbox_tree_update(struct mailbox_tree_context *tree, const char *path);
+
+struct mailbox_tree_iterate_context *
+mailbox_tree_iterate_init(struct mailbox_tree_context *tree,
+ struct mailbox_node *root, unsigned int flags_mask);
+struct mailbox_node *
+mailbox_tree_iterate_next(struct mailbox_tree_iterate_context *ctx,
+ const char **path_r);
+void mailbox_tree_iterate_deinit(struct mailbox_tree_iterate_context **ctx);
#endif
More information about the dovecot-cvs
mailing list